Ray to Ellipsoid Intersection
Took me a while to find a proper/working algorithm for Ray to Ellipsoid intersection that gave me the distance back, so I figured I’d repost it here, perhaps Google will rate it highly! :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public static float? RayToEllipsoid(ref Ray ray, ref BoundingEllipsoid ellipsoid)
{
// Source: http://www.ogre3d.org/forums/viewtopic.php?f=2&t=26442&start=0
Ray transformedRay = ray;
transformedRay.Position -= ellipsoid.Center;
transformedRay.Direction.Normalize();
float a = ((transformedRay.Direction.X * transformedRay.Direction.X) / (ellipsoid.Radius.X * ellipsoid.Radius.X))
+ ((transformedRay.Direction.Y * transformedRay.Direction.Y) / (ellipsoid.Radius.Y * ellipsoid.Radius.Y))
+ ((transformedRay.Direction.Z * transformedRay.Direction.Z) / (ellipsoid.Radius.Z * ellipsoid.Radius.Z));
float b = ((2 * transformedRay.Position.X * transformedRay.Direction.X) / (ellipsoid.Radius.X * ellipsoid.Radius.X))
+ ((2 * transformedRay.Position.Y * transformedRay.Direction.Y) / (ellipsoid.Radius.Y * ellipsoid.Radius.Y))
+ ((2 * transformedRay.Position.Z * transformedRay.Direction.Z) / (ellipsoid.Radius.Z * ellipsoid.Radius.Z));
float c = ((transformedRay.Position.X * transformedRay.Position.X) / (ellipsoid.Radius.X * ellipsoid.Radius.X))
+ ((transformedRay.Position.Y * transformedRay.Position.Y) / (ellipsoid.Radius.Y * ellipsoid.Radius.Y))
+ ((transformedRay.Position.Z * transformedRay.Position.Z) / (ellipsoid.Radius.Z * ellipsoid.Radius.Z))
- 1;
float d = ((b * b) - (4.0f * a * c));
if (d < 0)
{
return null;
}
else
{
d = (float)Math.Sqrt(d);
}
float hit = (-b + d) / (2.0f * a);
float hitsecond = (-b - d) / (2.0f * a);
if (hit < hitsecond)
{
return hit;
}
else
{
return hitsecond;
}
} |