Ray-Torus Intersection
int Torus::line_intersect(float ax, float ay, float az,
float bx, float by, float bz,
int * num_intersections,
float * intersections,
float * shade) const
//
// Intersect ray
// [ax] [bx]
// [ay] + t [by]
// [az] [bz]
// with torus at origin, major radius R, minor radius r
//
{
// This struct is syntactic sugar so that a.b,
// (the dot product) looks just right (:-)
struct { float a,b; } a;
a.b = ax*bx + ay*by + az*bz;
a.a = ax*ax + ay*ay + az*az;
// Set up quartic in t:
//
// 4 3 2
// t + A t + B t + C t + D = 0
//
float R2 = R*R;
float K = a.a - r*r - R2;
float A = 4*a.b;
float B = 2*(2*a.b*a.b + K + 2*R2*bz*bz);
float C = 4*(K*a.b + 2*R2*az*bz);
float D = K*K + 4*R2*(az*az - r*r);
// Solve quartic...
double roots[4];
int nroots = solve_quartic(A,B,C,D,roots,SOLVE_ALL);
*num_intersections = 0;
while(nroots--)
{
float t = roots[nroots];
float x = ax + t*bx;
float y = ay + t*by;
float l = R*(M_PI/2 - atan2(y,x));
if (l <= vlength && l >= 0)
intersections[(*num_intersections)++] = t;
}
}