Getting the normal of line intersecting a body

Aug 16, 2011 at 4:57 AM
Edited Aug 16, 2011 at 4:59 AM

Problem (Hypothetical Situation):

Laser is a line originates at Vector2 Start, and ends at Vector2 End

If it intersects a body, I want to find the normal

Requested response includes code that instantaneously and efficiently find the normal of the first body

 

Research done:

I remembered that the DebugViewXNA displays the normal of collision between two bodies.

After inspecting the code, it looks like I just need to find the Point where Laser intersects Body.

From there, it looks like I will be able to return Point.Normal.

 

Ideas:

Admittedly, I have limited understanding behind the math of body collisions.

There is probably a more efficient way of doing this, but it is currently unresolved because:

1) I don't know how to invoke contact listener (as per Body.ContactList recommendation)

2) I don't know how to return the normal


 

Create a rectangular body of width=1, length=Distance from Start to End
Put the body's Center of Mass at Start 

Invoke ContactListener (how?)
if ContactList.Count=0 return -1
while (ContactList.Count>1) { Put Center of Mass at Beginning Lengt/=2h; Invoke listener
 while(ContactList.Count==0) Put Center of Mass at End Length/=2; Invoke listener


}
FirstBody=ContactList's element

How to return normal?

 

 

 

Much obliged,

Dennis

Aug 17, 2011 at 10:19 AM

why use a line if farseer haves rays?

all you need is a ray cast from A to B

Aug 23, 2011 at 11:42 PM
Edited Aug 24, 2011 at 12:02 AM

Thanks for the reply HellGate,

I got a working fixture.Raycast, and I'm stuck deciphering on what I can do with World.RayCast.

As far as I understand, Fixture.Raycast makes a RaycastOutput considering only one fixture

and World.Raycast considers all relevant fixtures.

 

Where does (f,p,n,fr) come from? 

I can kindof guess that 'f' is a fixture that World.Raycast is currently considering

'fr' is a list of fixtures in the raycast

'p' is some kind of position (exiting? entering)

'n' is a thundercat

 

So essentially, if this reasoning is right, can I:

 

 

/*noting that I haven't declared f,p,n,fr anywhere*/
mindist=9999;
Fixture closetFixture;

World.Raycast( (f,p,n,fr) => 
{
      dist=Vector2Distance(RayStart,f.Body.Position);
      if (dist < mindist)
      {
           mindist=dist;
           closestFixture=f;
      }
       

}
,RayStart,RayEnd);

/*Look at explosion.cs for RaycastOne
Why do they return fr?

Is fr[0] the closest instance?

what is the segment with body.UserData?*/

Aug 24, 2011 at 10:26 AM

World.Raycast(fixture, point, normal, fraction)

i never really worked with rays but i think fraction is the distance to the intersection.

so do something like that

World.Raycast( (f,p,n,fr) => 
{
      if (fr < minfraction)
      {
           minfraction=fr;
           closestFixture=f;
      }
}
and it should work fine
Aug 24, 2011 at 9:11 PM

If you use a world.raycast it gives you the normal. The test bed has a good example of it in the edgeshape test.

_world.RayCast((fixture, point, normal, fraction)=>               

^^

 

Debug draw the raycast with:

 if (_fixture != null)     

{               

debug.DrawPoint(_Point, 0.1f, new Color(1f, 0f, 0f));               

debug.DrawSegment(Point3, _Point, new Color(0.8f, 0.8f, 0.8f));              

 Vector2 H = _Point + .2f* _Normal;       << you will clearly see the normal, and you can take the normal value from the world raycast        

  debug.DrawSegment(_Point, H, new Color(0.9f, 0.9f, 0.4f));       

    }