This project has moved. For the latest updates, please go here.

Closest point to loopshape...

Mar 17, 2012 at 9:37 PM

I have a static body with a fixture that is a loopshape.  It's big and irregular.

I have another body at position P.

I want to figure out how far away P is from the loopshape.  In other words, I want the minimum distance I'd have to travel to intersect with any part of the loopshape.

Any ideas?  Loop through vertices on the loopshape to find the closest one, and then do some trig?

Or cast a bunch of rays from P...?


Mar 18, 2012 at 2:43 AM

Oh, one more note...  I don't care about the fixture of the body at position P.  Just how far away that actual position (vector) is from the loopshape.

Mar 18, 2012 at 2:35 PM
Edited Mar 18, 2012 at 3:46 PM

Raycast could work well and also give you some additional info like on what vector you need to move your body without much further effort. Looping through the vertices will basically give you how to move to intersect with a vertex which is not the same as intersecting with an edge. You can, of course,  construct the edges and find the distance between a point (body P's center) and line (e.g. with Farseer.Common.LineTools). Or you can find the closest vertex then construct the edges that vertex belongs to on the CCW and CW orientation and find out which line(edge) is closest (much speedier because of less calculations). 

The general case is called minimum distance between two polygons (e.g. Rotating Calipers algorithm for convex polygons):

You're lucky because from what you write you only need to use the center of body P in the calculations and not the fixture itself. 

Mar 21, 2012 at 5:14 AM

Thanks for your note.

Just to followup, I ended up casting rays.  It didn't work at first because I was stupid.  But then I became less stupid, and it started working better.

I always know the direction (quadrant) where the loopshape is.  So I have a loop that casts rays out at an angle between HalfTau and ThreeQuartersTau (down with Pi!  Long live Tau!)  I increment by 0.1 radians, so that gives me about 8-10 rays.  I then pick the shortest one and use that as my distance away.  It's not exact, but it works well enough for my purposes.