public override void setCenter(Vec c)
 {
     this.c = c;
 }
 public Surface()
 {
     color = new Vec(1, 0, 0);
     kd = 1.0;
     ks = 0.0;
     shine = 0.0;
     kt = 0.0;
     ior = 1.0;
 }
 /**
    * Adds vector such as:
    * this+=sB
    * @param: s The multiplier
    * @param: b The vector to be added
    */
 public void adds(double s, Vec b)
 {
     x += s * b.x;
     y += s * b.y;
     z += s * b.z;
 }
 public View(Vec from, Vec at, Vec up, double dist, double angle, double aspect)
 {
     this.from = from;
     this.at = at;
     this.up = up;
     this.dist = dist;
     this.angle = angle;
     this.aspect = aspect;
 }
 public static double dot(Vec a, Vec b)
 {
     return a.x * b.x + a.y * b.y + a.z * b.z;
 }
 /**
    * Substracs two vectors
    */
 public static Vec sub(Vec a, Vec b)
 {
     return new Vec(a.x - b.x, a.y - b.y, a.z - b.z);
 }
        public void render(Interval interval)
        {
            // Screen variables
            int[] row = new int[interval.width * (interval.yto - interval.yfrom)];
            int pixCounter = 0; //iterator

            // Rendering variables
            int x, y, red, green, blue;
            double xlen, ylen;
            Vec viewVec;

            viewVec = Vec.sub(view.at, view.from);

            viewVec.normalize();

            Vec tmpVec = new Vec(viewVec);
            tmpVec.scale(Vec.dot(view.up, viewVec));

            Vec upVec = Vec.sub(view.up, tmpVec);
            upVec.normalize();

            Vec leftVec = Vec.cross(view.up, viewVec);
            leftVec.normalize();

            double frustrumwidth = view.dist * Math.Tan(view.angle);

            upVec.scale(-frustrumwidth);
            leftVec.scale(view.aspect * frustrumwidth);

            Ray r = new Ray(view.from, voidVec);
            Vec col = new Vec();

            // Header for .ppm file
            // System.out.println("P3");
            // System.out.println(width + " " + height);
            // System.out.println("255");

            // All loops are reversed for 'speedup' (cf. thinking in java p331)

            // For each line
            for (y = interval.yfrom; y < interval.yto; y++)
            {
                ylen = (double)(2.0 * y) / (double)interval.width - 1.0;
                // System.out.println("Doing line " + y);
                // For each pixel of the line
                for (x = 0; x < interval.width; x++)
                {
                    xlen = (double)(2.0 * x) / (double)interval.width - 1.0;
                    r.D = Vec.comb(xlen, leftVec, ylen, upVec);
                    r.D.add(viewVec);
                    r.D.normalize();
                    col = trace(0, 1.0, r);

                    // computes the color of the ray
                    red = (int)(col.x * 255.0);
                    if (red > 255)
                        red = 255;
                    green = (int)(col.y * 255.0);
                    if (green > 255)
                        green = 255;
                    blue = (int)(col.z * 255.0);
                    if (blue > 255)
                        blue = 255;

                    checksum += red;
                    checksum += green;
                    checksum += blue;

                    // RGB values for .ppm file
                    // System.out.println(red + " " + green + " " + blue);
                    // Sets the pixels
                    row[pixCounter++] = alpha | (red << 16) | (green << 8) | (blue);
                } // end for (x)
            } // end for (y)
        }
 public static Vec comb(double a, Vec A, double b, Vec B)
 {
     return
       new Vec(a * A.x + b * B.x,
           a * A.y + b * B.y,
           a * A.z + b * B.z);
 }
 public Ray(Vec pnt, Vec dir)
 {
     P = new Vec(pnt.x, pnt.y, pnt.z);
     D = new Vec(dir.x, dir.y, dir.z);
     D.normalize();
 }
 public Ray()
 {
     P = new Vec();
     D = new Vec();
 }
 public abstract void setCenter(Vec c);
 public abstract Vec normal(Vec pnt);
 public Light(double x, double y, double z, double brightness)
 {
     this.pos = new Vec(x, y, z);
     this.brightness = brightness;
 }
 /**
    * Copy constructor
    */
 public Vec(Vec a)
 {
     x = a.x;
     y = a.y;
     z = a.z;
 }
        /**
           * Returns the shaded color
           * @return The color in Vec form (rgb)
           */
        Vec shade(int level, double weight, Vec P, Vec N, Vec I, Isect hit)
        {
            double n1, n2, eta, c1, cs2;
            Vec r;
            Vec tcol;
            Vec R;
            double t, diff, spec;
            Surface surf;
            Vec col;
            int l;

            col = new Vec();
            surf = hit.surf;
            R = new Vec();
            if (surf.shine > 1e-6)
            {
                R = SpecularDirection(I, N);
            }

            // Computes the effectof each light
            for (l = 0; l < lights.Length; l++)
            {
                L.sub2(lights[l].pos, P);
                if (Vec.dot(N, L) >= 0.0)
                {
                    t = L.normalize();

                    tRay.P = P;
                    tRay.D = L;

                    // Checks if there is a shadow
                    if (Shadow(tRay, t) > 0)
                    {
                        diff = Vec.dot(N, L) * surf.kd *
                          lights[l].brightness;

                        col.adds(diff, surf.color);
                        if (surf.shine > 1e-6)
                        {
                            spec = Vec.dot(R, L);
                            if (spec > 1e-6)
                            {
                                spec = Math.Pow(spec, surf.shine);
                                col.x += spec;
                                col.y += spec;
                                col.z += spec;
                            }
                        }
                    }
                } // if
            } // for

            tRay.P = P;
            if (surf.ks * weight > 1e-3)
            {
                tRay.D = SpecularDirection(I, N);
                tcol = trace(level + 1, surf.ks * weight, tRay);
                col.adds(surf.ks, tcol);
            }
            if (surf.kt * weight > 1e-3)
            {
                if (hit.enter > 0)
                    tRay.D = TransDir(null, surf, I, N);
                else
                    tRay.D = TransDir(surf, null, I, N);
                tcol = trace(level + 1, surf.kt * weight, tRay);
                col.adds(surf.kt, tcol);
            }

            // garbaging...
            tcol = null;
            surf = null;

            return col;
        }
 /**
    * adds: Returns a new vector such as
    * new = sA + B
    */
 public static Vec adds(double s, Vec a, Vec b)
 {
     return new Vec(s * a.x + b.x, s * a.y + b.y, s * a.z + b.z);
 }
 /**
    * Return the Vector's reflection direction
    * @return The specular direction
    */
 Vec SpecularDirection(Vec I, Vec N)
 {
     Vec r;
     r = Vec.comb(1.0 / Math.Abs(Vec.dot(I, N)), I, 2.0, N);
     r.normalize();
     return r;
 }
 public static Vec cross(Vec a, Vec b)
 {
     return
       new Vec(a.y * b.z - a.z * b.y,
           a.z * b.x - a.x * b.z,
           a.x * b.y - a.y * b.x);
 }
 /**
    * Return the Vector's transmission direction
    */
 Vec TransDir(Surface m1, Surface m2, Vec I, Vec N)
 {
     double n1, n2, eta, c1, cs2;
     Vec r;
     n1 = m1 == null ? 1.0 : m1.ior;
     n2 = m2 == null ? 1.0 : m2.ior;
     eta = n1 / n2;
     c1 = -Vec.dot(I, N);
     cs2 = 1.0 - eta * eta * (1.0 - c1 * c1);
     if (cs2 < 0.0)
         return null;
     r = Vec.comb(eta, I, eta * c1 - Math.Sqrt(cs2), N);
     r.normalize();
     return r;
 }
 public static Vec mult(Vec a, Vec b)
 {
     return new Vec(a.x * b.x, a.y * b.y, a.z * b.z);
 }
        Vec v, b; // temporary vecs used to minimize the memory load

        #endregion Fields

        #region Constructors

        public Sphere(Vec center, double radius)
        {
            c = center;
            r = radius;
            r2 = r * r;
            v = new Vec();
            b = new Vec();
        }
 /**
    * Add a vector to the current vector
    * @param: a The vector to be added
    */
 public void add(Vec a)
 {
     x += a.x;
     y += a.y;
     z += a.z;
 }
 public override Vec normal(Vec p)
 {
     Vec r;
     r = Vec.sub(p, c);
     r.normalize();
     return r;
 }
 public void comb2(double a, Vec A, double b, Vec B)
 {
     x = a * A.x + b * B.x;
     y = a * A.y + b * B.y;
     z = a * A.z + b * B.z;
 }
 /**
    * Substracts two vects and places the results in the current vector
    * Used for speedup with local variables -there were too much Vec to be gc'ed
    * Consumes about 10 units, whether sub consumes nearly 999 units!!
    * cf thinking in java p. 831,832
    */
 public void sub2(Vec a, Vec b)
 {
     this.x = a.x - b.x;
     this.y = a.y - b.y;
     this.z = a.z - b.z;
 }