Quadric.java
package com.gwief.jTrace;
/*
Quadric.java by Damian Newport
Given a Ray and some co-efficients can find intersection and normal of any
quadratic of equation:
AX^2 + BY^2 + CZ^2 + J = 0
This is used by Cylinder, Cone, and Hyperboloid
*/
public class Quadric {
/*
General quadric surface equation:
F(x, y, z) = Ax^2 + By^2 + Cz^2 + 2Dxy+ 2Exz + 2Fyz + Gx + Hy + Iz + J = 0
ignore all but a,b,c,j for efficiency and cause were not doing a paraboloid
and thus don't need them
*/
/* takes a Ray, returns a array of length 0 if miss,
length 2 filled with intersections if we hit */
public static final double[] intersect(Ray i, double A, double B, double C, double J){
double xo = i.origin.x;
double yo = i.origin.y;
double zo = i.origin.z;
double xd = i.direction.x;
double yd = i.direction.y;
double zd = i.direction.z;
double[] result = new double[0];
/* work out coefficients */
double a = A*xd*xd + B*yd*yd + C*zd*zd;
double b = 2 * (A*xo*xd + B*yo*yd + C*zo*zd);
double c = A*xo*xo + B*yo*yo + C*zo*zo + J;
/* if its a plane */
if (a < rayTrace.TINY){
result = new double[2];
double temp = -c / b;
result[0] = temp;
result[1] = temp;
}
double check = b*b - 4*a*c;
/* if we don't hit anything */
if (check < 0){
return result;
}
check = Math.sqrt(check);
double temp1,temp2;
temp2 = 2*a;
temp1 = (-b - check)/temp2;
temp2 = (-b + check)/temp2;
result = new double[2];
if (temp1 < temp2){
result[0] = temp1;
result[1] = temp2;
}else{
result[0] = temp2;
result[1] = temp1;
}
if (result[1] < 0){
return new double[0];
}
return result;
}
/* takes a intersection point as a Vector3D, and the co-efficiecients
returns the normal as a vector3D */
public static final Vector3D normal(Vector3D i, double A, double B, double C, double J){
Vector3D n = new Vector3D();
n.x = 2 * A*i.x;
n.y = 2 * B*i.y;
n.z = 2 * C*i.z;
return n;
}
}