80179

What is the best approach to compute efficiently the first intersection between a viewing ray and a

Question:

For instance:

An approach to compute efficiently the first intersection between a viewing ray and a set of three objects: one sphere, one cone and one cylinder (other 3D primitives).

Answer1:

What you're looking for is a spatial partitioning scheme. There are a lot of options for dealing with this, and lots of research spent in this area as well. A good read would be Christer Ericsson's <a href="http://realtimecollisiondetection.net/" rel="nofollow">Real-Time Collision Detection</a>.

One easy approach covered in that book would be to define a grid, assign all objects to all cells it intersects, and walk along the grid cells intersecting the line, front to back, intersecting with each object associated with that grid cell. Keep in mind that an object might be associated with more grid-cells, so the intersection point computed might actually not be in the current cell, but actually later on.

The next question would be how you define that grid. Unfortunately, there's no one good answer, and you need to consider what approach might fit your scenario best.

Other partitioning schemes of interest are different tree structures, such as <a href="http://en.wikipedia.org/wiki/Kd-tree" rel="nofollow">kd-</a>, <a href="http://en.wikipedia.org/wiki/Octree" rel="nofollow">Oct-</a> and <a href="http://en.wikipedia.org/wiki/Binary_space_partitioning" rel="nofollow">BSP-trees</a>. You could even consider using trees combined with a grid.

<b>EDIT</b><br /> As pointed out, if your set is actually these three objects, you're definately better of just intersecting each one, and just pick the earliest one. If you're looking for ray-sphere, ray-cylinder, etc, intersection tests, these are not really hard and a quick google should supply all the math you might possibly need. :)

Answer2:

"computationally efficient" depends on how large the set is.

For a trivial set of three, just test each of them in turn, it's really not worth trying to optimise.

For larger sets, look at data structures which divide space (e.g. KD-Trees). Whole chapters (and indeed whole books) are dedicated to this problem. My favourite reference book is <a href="http://rads.stackoverflow.com/amzn/click/0122861604" rel="nofollow">An Introduction to Ray Tracing</a> (ed. Andrew. S. Glassner)

Alternatively, if I've misread your question and you're actually asking for algorithms for ray-object intersections for specific <em>types</em> of object, see the same book!

Answer3:

Well, it depends on what you're really trying to do. If you'd like to produce a solution that is correct for almost every pixel in a simple scene, an extremely quick method is to pre-calculate "what's in front" for each pixel by pre-rendering all of the objects with a unique identifying color into a background item buffer using scan conversion (aka the z-buffer). This is sometimes referred to as an item buffer.

Using that pre-computation, you then know what will be visible for almost all rays that you'll be shooting into the scene. As a result, your ray-environment intersection problem is greatly simplified: each ray hits one specific object.

When I was doing this <a href="http://portal.acm.org/citation.cfm?id=833838" rel="nofollow">many years ago</a>, I was producing real-time raytraced images of admittedly simple scenes. I haven't revisited that code in quite a while but I suspect that with modern compilers and graphics hardware, performance would be orders of magnitude better than I was seeing then.

PS: I first read about the item buffer idea when I was doing my literature search in the early 90s. I originally found it mentioned in (I believe) an ACM paper from the late 70s. Sadly, I don't have the source reference available but, in short, it's a very old idea and one that works really well on scan conversion hardware.

Answer4:

I assume you have a ray d = (dx,dy,dz), starting at o = (ox,oy,oz) and you are finding the parameter t such that the point of intersection p = o+d*t. (Like <a href="http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/" rel="nofollow">this</a> page, which describes ray-plane intersection using P2-P1 for d, P1 for o and u for t)

The first question I would ask is "Do these objects intersect"?

If not then you can cheat a little and check for ray collisions in order. Since you have three objects that may or may not move per frame it pays to pre-calculate their distance from the camera (e.g. from their centre points). Test against each object in turn, by distance from the camera, from smallest to largest. Although the empty space is the most expensive part of the render now, this is more effective than just testing against all three and taking a minimum value. If your image is high res then this is especially efficient since you amortise the cost across the number of pixels.

Otherwise, test against all three and take a minimum value...

In other situations you may want to make a hybrid of the two methods. If you can test two of the objects in order then do so (e.g. a sphere and a cube moving down a cylindrical tunnel), but test the third and take a minimum value to find the final object.

Recommend

  • UIToolbar not transparent on iPad2
  • Can you do symmetric encryption on SAML attributes in SAML 2.0?
  • C++ multiple threads and vectors
  • Logic in property getters [closed]
  • WCF Add Header Issue with AddressHeader.CreateAddressHeader() method
  • Program doesn't stop after exception
  • Exception in async task gets intercepted in Visual Studio
  • ArrayList in C#
  • Get the computer user name in a web application
  • Can I have the market update an app that was installed from else where?
  • Grails/Roo for a .Net developer
  • What is the first step to using a REST API in Rails?
  • What is wrong in my MVC implementation?
  • Can an iframe pop up a Lightbox-style box?
  • Loopback validation on Properties who's types are other Models
  • Correctly Importing Apache Commons Math Package
  • android-support-v7-appcompat has same attrs as actionbarsherlock library
  • MySQL: Difference between `… ADD INDEX(a); … ADD INDEX(b);` and `… ADD INDEX(a,b);`?
  • How do you keep a running instance for Google App Engine
  • Is there a way to call library thread-local init/cleanup on thread creation/destruction?
  • Unique Permutations - with exceptions
  • EntLib Way to Bind “Null” Value to Parameter
  • Accessing Rows In A LINQ Result Without A Foreach Loop?
  • Xamarin MonoAndroid Azure mobile service InsertAsync
  • C# fibonacci function returning errors
  • D3 get axis values on zoom event
  • OOP Javascript - Is “get property” method necessary?
  • Cannot resolve symbol 'MyApi'
  • Seeking advice on Jetty HttpClient Hang
  • Illegal mix of collations for operation for date/time comparison
  • Javascript convert timezone issue
  • Adding custom controls to a full screen movie
  • Google cloud sdk not working when python points python3
  • Calling of Constructors in a Java
  • Buffer size for converting unsigned long to string
  • using HTMLImports.whenReady not working in chrome
  • How do you join a server to an Active Directory (domain)?
  • -fvisibility=hidden not passed by compiler for Debug builds
  • How can I remove ASP.NET Designer.cs files?
  • Android Heatmap on canvas or ImageView