public bool RayIntersection(Ray3D ray, out Point3D[] result)
{
double cx = this.center.X;
double cy = this.center.Y;
double cz = this.center.Z;
double r = this.radius;
double x1 = ray.Origin.X;
double y1 = ray.Origin.Y;
double z1 = ray.Origin.Z;
double dx = ray.Direction.X;
double dy = ray.Direction.Y;
double dz = ray.Direction.Z;
// Quadratic solving
double a = (dx * dx) + (dy * dy) + (dz * dz);
double b = (2 * dx * (x1 - cx)) + (2 * dy * (y1 - cy)) + (2 * dz * (z1 - cz));
double c = (x1 * x1) + (y1 * y1) + (z1 * z1) + (cx * cx) + (cz * cz) + (cy * cy) - (2 * ((cy * y1) + (cz * z1) + (cx * x1))) - (r * r);
// Discriminant
double q = (b * b) - (4 * a * c);
// We have at least one possible intersection
if (q >= 0)
{
double q2 = Math.Sqrt((b * b) - (4 * a * c));
// First root
double t1 = (-b + q2) / (2 * a);
// Second root
double t2 = (-b - q2) / (2 * a);
if (t1 >= 0 && t2 >= 0 && !t1.Equals(t2))
{
var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));
result = t1 < t2 ? new[] { i1, i2 } : new[] { i2, i1 };
return true;
}
if (t1 >= 0)
{
var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
result = new[] { i1 };
return true;
}
if (t2 >= 0)
{
var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));
result = new[] { i2 };
return true;
}
}
result = null;
return false;
}