GwieF.com : project.GrieF.com : Classes : Cone
logo

Cone.java


package com.gwief.jTrace;

/*
    Cone.java by Damian Newport
    uses Quadric.java to implement a cone
*/

public class Cone{

    public static final double[] intersect(Ray a){
        double[] box = Box.intersect(a);
        
        // do we hit the box?
        if (box.length == 0){
            return new double[0];
        }
        
        // if we got here we hit the box - lets test the cone
        // move the cone up so we don't get >< shape
        Ray i = new Ray(a);
        i.origin.y -= 0.5;

                                         // A,  B, C, J 
        double[] con = Quadric.intersect(i, 4, -1, 4, 0);
 
        // do we hit the the cone?
        if (con.length == 0){
            return new double[0];
        }
        
        if (rayTrace.bugmode){
            System.out.println("Cone.box[0] = " + box[0]);
            System.out.println("Cone.box[1] = " + box[1]);
            System.out.println("Cone.con[0] = " + con[0]);
            System.out.println("Cone.con[1] = " + con[1]);
        }
        
        // if we get here we've scored
        // now just have to work out where 

        if (con[0] > box[1]){
            return new double[0];
        }
        if (box[0] > con[1]){
            return new double[0];
        }
        if ((con[0] < box[0]) && (con[1] > box[1])){    // if both outside = miss
            return new double[0];
        }
        if ((con[0] > box[0]) && (con[1] < box[1])){    // if both inside return cone
            return con;
        }
        
        // one intersect is inside
        if (con[1] > box[1]){       // if con[0] is inside
            // if box[0] is the base we return box[0] and con [0], else con[0] and box[1];
            Vector3D temp = new Vector3D(a.direction);
            temp.multiply(box[0]);
            temp.add(a.origin);
            if ((0.5+temp.y) < rayTrace.TINY){      // box[0] = base
                box[1] = con[0];
                return box;
            }else{
                con[1] = box[1];        // box[0] != base
                return con;
            }
        }
        
        // con[1] is inside
        // if box[0] is the base we return box[0] and con [1], else con[1] and box[1];
        Vector3D temp = new Vector3D(a.direction);
        temp.multiply(box[0]);
        temp.add(a.origin);
        if ((0.5+temp.y) < rayTrace.TINY){      // box[0] = base
            box[1] = con[1];
            return box;
        }else{
            box[0] = con[1];        // box[0] != base
            return box;
        }
        
    }
    
    public static final Vector3D normal(Vector3D a){
        
        /* if it intersects with the box bit */
        
        if ((0.5+a.y) < rayTrace.TINY){
            return new Vector3D(0,-1,0);
        }

        /* else it intersects with the cone */
        /* move the cone 'down' so the point is at the top */
        Vector3D temp = new Vector3D(a);
        temp.y -= 0.5;
        
                                 /* A,  B, C, J */
        return Quadric.normal(temp, 4, -1, 4, 0);
    }
}