# Ray to spherically capped cone

This topic is 4083 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello I am looking for a fast way to ray trace a cone. My ray definition looks like this... struct Ray { float3 Origin; // the origin of the ray in world space float3 Direction; // the direction of the ray }; My cone is semi-infinite with a spherical cap: struct Cone { float3 Apex; // the position of the apex in world space float3 Direction; // the direction of the cone float Radius; // the radius of the cap sphere at the apex float SpreadAngle; // Cos(Theta) }; What I would like is to know if the ray intersects the cone and also if the ray does intersect what the thickness is from the point of entry to the point of exit. I've tried looking around to find the answer but the solutions I saw weren't very practical and didn't deal with spherically capped cones. If anyone could help me figure out how to do it I'd be very grateful. thanks!

##### Share on other sites
Just find where the ray enters the cone. If the radius of the cone at that point is greater than the radius of the cap sphere then the ray entered at that point; otherwise it either entered through the cap or didn't enter at all, so you find where it entered the sphere. The same can be done for the exit point.

##### Share on other sites
Bare with me, this is just off the top of my head.

The first thing I would do is transform the problem into a space where the cone's apex and direction are the origin and Z-axis, respectively. The most important thing here is to make sure you transform the ray correctly. The easiest way to do this is to create an arbitrary basis where the cone's direction is the Z-axis, and the X- and Y-axis can be anything provided they're perpendicular to each other and the Z-axis. Plug those axis into the first three columns of a 4x4 matrix 'M', then plug the cone's apex into the fourth column. Basically, it's a transformation matrix. Take the ray's origin 'O' and direction 'D' and make homogeneous 4D vectors out of them (where W is 1 for the origin and 0 for the ray), then do M-1O and M-1D to get the new origin and direction for the ray.

This transformation allows us to describe the cone using the equation x2 + y2 = Az2, where A is some factor that takes into account the spread of the cone. When y is 0, we have the relation x2 = Az2, or x = sqrt(A)z, which is the same as sqrt(A) = x/z. Well is just so happens that the spread of the cone, cos(θ), also happens to be x/z when y is 0. This means that sqrt(A) = cos(θ), or A = cos2(θ).

If we take the parametric equation of the ray in this new space and plug it into the above equation, you should be able to solve for the parameter 't', which will give you the intersection point. You also mentioned that there was a spherical cap. To this end I propose you do two intersection tests, a ray-cone test and a ray-sphere test, and compare the results. If the ray origin is within the cone spread, you know that it can only intersect the cap, so you only test against the sphere. If the ray origin is inside the sphere but outside the cone, you know it can only intersect the cone. If it's outside both the sphere and the cone, then you perform both tests and use the parameters and intersection points to determine which feature (the cone or the sphere) the ray actually hit. One that is done, you transform the solution 'P' back into the original space using MP (where M is the matrix we built previously).

I'm sorry if that was a little incoherent, like I said it was all off the top of my head and it's pretty late :) It certainly isn't the fastest or most clever method, but it should work if I didn't forget anything. Maybe someone else has something better...

##### Share on other sites
Hi Zipster,

Thanks for the tips...

I like the idea of doing the test in cone space although I'm still not clear on how I get the thickness from the point of intersection to the exit point. Also it seems like there may be another way to unify the spherical cap into the mix without an additional special case test but I'm not seeing it.

Another problem is the matrix inversion. The code is going to be running on the GPU and performing the matrix inversion won't be good. I can get around this by doing the calculations up front in the application though.

I made this drawing to help visualize it
http://webclips.s3.amazonaws.com/RayCone.jpg

best

##### Share on other sites
Quote:
 Original post by smudgeI like the idea of doing the test in cone space although I'm still not clear on how I get the thickness from the point of intersection to the exit point. Also it seems like there may be another way to unify the spherical cap into the mix without an additional special case test but I'm not seeing it.

In that case you would do the intersection test again, this time having the ray start at the entrance point. It will next intersect the cone on its way out. You may get a solution for the exit that's the same (or extremely close to) the entrance point - just ignore that one and take the next one.

And unfortunately there isn't another (or at least easy) way to represent the spherical cap other than the intersection of the cone and the sphere. Not even a flat cap is easier, you still need to represent it as the intersection of a cone and a half-space.

Quote:
 Another problem is the matrix inversion. The code is going to be running on the GPU and performing the matrix inversion won't be good. I can get around this by doing the calculations up front in the application though.

Since we constructed our matrix out of a rotation and a translation, we can use this nifty trick to invert the matrix:

Where R is the rotation sub-matrix and 'd' is the translation. As you see, it reduces into a transpose, negation, and matrix-vector multiplication.

##### Share on other sites
Aha, thanks, yes that invert makes sense.

Okay, I'll try it out this afternoon and see if I can get it going.

I got myself a copy of "Geometric Tools for Computer Graphics" this weekend and that looks like it might be of assistance (though it is pretty heavy going). I did notice a section on cone testing with an huge function provided to do the test. I'm guessing/hoping that the code is just so long because it is extremely robust and I might not need all of it. Also probably there are a bunch of early-outs that are useful.

Thanks again for the help

1. 1
Rutin
69
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633430
• Total Posts
3011827
• ### Who's Online (See full list)

There are no registered users currently online

×