import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.picking.*;

public class divergingLens extends myShape 
{    
    private float oneOverSquRoot2=0.707107f;
    private float radius=1.0f;
    private float halflength=0.3f;
    private float halfInnerLength=0.1f;
    // 8 vertices going anticlockwise round the perimeter at the front
        private Point3f vertex0=new Point3f(radius,0.0f,halflength);
    private Point3f vertex1=new Point3f(radius*oneOverSquRoot2,radius*oneOverSquRoot2,halflength);
    private Point3f vertex2=new Point3f(0.0f,radius,halflength);
    private Point3f vertex3=new Point3f(-radius*oneOverSquRoot2,radius*oneOverSquRoot2,halflength);
        private Point3f vertex4=new Point3f(-radius,0.0f,halflength);
    private Point3f vertex5=new Point3f(-radius*oneOverSquRoot2,-radius*oneOverSquRoot2,halflength);
    private Point3f vertex6=new Point3f(0.0f,-radius,halflength);
    private Point3f vertex7=new Point3f(radius*oneOverSquRoot2,-radius*oneOverSquRoot2,halflength);
    // 8 vertices going anticlockwise round the perimeter at the back
        private Point3f vertex0b=new Point3f(radius,0.0f,-halflength);
    private Point3f vertex1b=new Point3f(radius*oneOverSquRoot2,radius*oneOverSquRoot2,-halflength);
    private Point3f vertex2b=new Point3f(0.0f,radius,-halflength);
    private Point3f vertex3b=new Point3f(-radius*oneOverSquRoot2,radius*oneOverSquRoot2,-halflength);
        private Point3f vertex4b=new Point3f(-radius,0.0f,-halflength);
    private Point3f vertex5b=new Point3f(-radius*oneOverSquRoot2,-radius*oneOverSquRoot2,-halflength);
    private Point3f vertex6b=new Point3f(0.0f,-radius,-halflength);
    private Point3f vertex7b=new Point3f(radius*oneOverSquRoot2,-radius*oneOverSquRoot2,-halflength);
    // vertex in front
    private Point3f vertex8=new Point3f(0.0f,0.0f,halfInnerLength);
    // vertex behind
    private Point3f vertex9=new Point3f(0.0f,0.0f,-halfInnerLength);
    
    private Point3f[] vertices= 
    {
        // front face going anticlockwise
            vertex8, vertex0, vertex1,  
            vertex8, vertex1, vertex2,
            vertex8, vertex2, vertex3,  
            vertex8, vertex3, vertex4,
            vertex8, vertex4, vertex5,
            vertex8, vertex5, vertex6,
            vertex8, vertex6, vertex7,
            vertex8, vertex7, vertex0,
            // back face
            vertex9, vertex4b, vertex3b,
            vertex9, vertex3b, vertex2b,
            vertex9, vertex2b, vertex1b,
            vertex9, vertex1b, vertex0b,
            vertex9, vertex0b, vertex7b,
            vertex9, vertex7b, vertex6b,
            vertex9, vertex6b, vertex5b,
            vertex9, vertex5b, vertex4b,
            // sides
            vertex0, vertex0b, vertex1b,
            vertex0, vertex1b, vertex1,
            vertex1, vertex1b, vertex2b,
            vertex1, vertex2b, vertex2,
            vertex2, vertex2b, vertex3b,
            vertex2, vertex3b, vertex3,
            vertex3, vertex3b, vertex4b,
            vertex3, vertex4b, vertex4,
            vertex4, vertex4b, vertex5b,
            vertex4, vertex5b, vertex5,
            vertex5, vertex5b, vertex6b,
            vertex5, vertex6b, vertex6,
            vertex6, vertex6b, vertex7b,
            vertex6, vertex7b, vertex7,
            vertex7, vertex7b, vertex0b,
            vertex7, vertex0b, vertex0
    };

    private Point2f texCoord[] = 
    {
        new Point2f(0.0f, 0.0f),
            new Point2f(1.0f, 0.0f),
        new Point2f(0.5f,((float)Math.sqrt(3.0))/2.0f)
    };
    
    private Color3f colour[]=
        {
            new Color3f(1.0f, 0.0f, 0.0f),
            new Color3f(0.0f, 1.0f, 0.0f),
            new Color3f(0.0f, 0.0f, 1.0f),
            new Color3f(1.0f, 1.0f, 0.0f),
            new Color3f(0.0f, 1.0f, 1.0f),
            new Color3f(1.0f, 0.0f, 1.0f)
        };

    public divergingLens() 
    {
            int i;

            TriangleArray tetra=new TriangleArray(vertices.length,TriangleArray.COORDINATES|
                TriangleArray.NORMALS|TriangleArray.TEXTURE_COORDINATE_2|TriangleArray.COLOR_3);
                   
                // set the vertex points                
            tetra.setCoordinates(0,vertices);
        for(i=0;i<vertices.length;i++) 
        {
            tetra.setTextureCoordinate(i,texCoord[i%3]);
        }
        
        // set the colours         
        for(i=0;i<vertices.length;i++)
        {
            tetra.setColor(i,colour[i%6]);
        }
         
        // set the normals
            int face;
            Vector3f normal=new Vector3f();
            Vector3f vector1=new Vector3f();
            Vector3f vector2=new Vector3f();
            Point3f [] points=new Point3f[3];
            for(i=0;i<3;i++)points[i]=new Point3f();

            for(face=0;face<vertices.length/3;face++) 
            {
                tetra.getCoordinates(face*3,points);
                vector1.sub(points[1],points[0]);
                vector2.sub(points[2],points[0]);
                normal.cross(vector1,vector2);
                normal.normalize();
                for (i=0;i<3;i++) 
                {
                        tetra.setNormal((face*3+i),normal);
                }
            }
            
            // create the shape
            Appearance thisAppearance=new Appearance();
            this.setGeometry(tetra);
            this.setAppearance(thisAppearance);
    }
    
    public String getName()
    {
        return"diverging lens";
    }
    
    public Point3f getTriangleCoordinates(int i)
    {
        return vertices[i];
    }    
    
    public int getNumberTriangles()
    {
        return vertices.length/3;
    }
}
