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;
}
} |
1 Comment
Other Links to this Post
RSS feed for comments on this post. TrackBack URI
By Rasmus, September 26, 2011 @ 12:33
Thanks Bjarni, I was just working on the same thing. Got the sphere intersection right, but when the world transformation scaling came into play it wasn’t just as fun.. But this solves it all :)