@Override
public Intersection intersect(Ray r)
{
Intersection result = new Intersection();
Ray ray = worldToObject.transform(r);
// compute quadratic sphere coefficients
double a = ray.d.x*ray.d.x +ray.d.y*ray.d.y + ray.d.z*ray.d.z;
double b = 2 * (ray.d.x*ray.o.x + ray.d.y*ray.o.y + ray.d.z* ray.o.z);
double c = ray.o.x*ray.o.x + ray.o.y*ray.o.y + ray.o.z*ray.o.z - radius*radius;
// solve quadratic equation for t values
double[] t = Global.quadratic(a, b, c);
if (t == null)
return result;
// compute intersection distance along ray
if (t[0] > ray.maxt || t[1] < ray.mint)
return result;
double thit = t[0];
if (t[0] < ray.mint)
{
thit = t[1];
if (thit > ray.maxt)
return result;
}
// compute sphere hit position and phi
Point phit = ray.eval(thit);
if (phit.x == 0.0 && phit.y == 0.0)
phit.x = 1e-5 * radius;
double phi = Math.atan2(phit.y, phit.x);
if (phi < 0.0)
phi += 2 * Math.PI;
// test sphere intersection against clipping parameters
if ( (zmin > -radius && phit.z < zmin) ||
(zmax > radius && phit.z > zmax) || phi > phiMax )
{
if (thit == t[1] || t[1] > ray.maxt)
return result;
thit = t[1];
// compute sphere hit position and phi
phit = ray.eval(thit);
if (phit.x == 0.0 && phit.y == 0.0)
phit.x = 1e-5 * radius;
phi = Math.atan2(phit.y, phit.x);
if (phi < 0.0)
phi += 2 * Math.PI;