public static Color trace(Ray r) {
   Point pt = null;
   Point nPt;
   ObjectR oInter = null;
   double minDist = Double.MAX_VALUE;
   for (ObjectR o : ObjectR.objects) {
     nPt = o.intersect(r);
     double dist = calc.distance(nPt.coord, cam.point.coord);
     if (dist < minDist) {
       pt = nPt;
       minDist = dist;
       oInter = o;
     }
   }
   if (pt != null) {
     // Find Light source
     for (Light s : Light.lights) {
       Ray shadow = new Ray(pt.coord, s.dim);
       for (ObjectR oShadow : ObjectR.objects) {
         if (!Light.lights.contains(oShadow) && oShadow.intersect(shadow) != null) {
           if (oShadow == oInter) {
             return shade(oInter, pt, s, cam);
           } else {
             return black;
           }
         }
       }
       return shade(oInter, pt, s, cam);
     }
   }
   return background;
 }
 public static double diffuse(ObjectR o, Point p, Light l) {
   double[] norm = calc.normalize(o.normal(p));
   double[] light = calc.normalize(calc.sub(l.dim, p.coord));
   double factor = calc.dot(norm, light);
   factor = Math.max(factor, 0);
   return o.kd() * factor + o.ka();
 }
 public static double specular(ObjectR o, Point p, Light l, Camera c) {
   double[] norm = calc.normalize(o.normal(p));
   double[] eye = calc.normalize(calc.sub(c.point.coord, p.coord));
   double[] light = calc.normalize(calc.sub(l.dim, p.coord));
   double[] h = calc.normalize(calc.add(eye, light));
   double factor = calc.dot(norm, h);
   factor = Math.max(factor, 0);
   return o.ks() * Math.pow(factor, o.n());
 }
 public static Color shade(ObjectR o, Point p, Light l, Camera cam) {
   double c1 = diffuse(o, p, l);
   c1 += specular(o, p, l, cam);
   Color c = o.color(p);
   int r = Math.min(255, (int) (c.getRed() * c1));
   int g = Math.min(255, (int) (c.getGreen() * c1));
   int b = Math.min(255, (int) (c.getBlue() * c1));
   return new Color(r, g, b);
 }