## Box2D C++ tutorials - Ray casting

Last edited: July 14 2013

Chinese version -> 中文

### Ray casting

Ray casting is often used to find out what objects are in a certain part of the world. A ray is just a straight line, and we can use a function provided by Box2D to check if the line crosses a fixture. We can also find out what the normal is at the point the line hits the fixture.

Here is the function I'm talking about, which returns true if the ray hits the fixture. Notice it's a member of the b2Fixture class, which means we'll first need to have one of those to cast a ray against.
 ```1 ``` `  bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input);`
Now what are these input and output parameters. Well, straight from the source code here is what a b2RayCastInput contains:
 ```1 2 3 4 5 6 ``` ```  // Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).   struct b2RayCastInput   {       b2Vec2 p1, p2;       float32 maxFraction;   };```
The points p1 and p2 are used to define a direction for the ray, and the maxFraction specifies how far along the ray should be checked for an intersection. The following image may make this clearer. A maxFraction of 1 simply means the segment from p1 to p2, which in this case would not intersect the shape, but a maxFraction of 2 would. And here is what a b2RayCastOutput contains:
 ```1 2 3 4 5 6 7 ``` ```  // Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2   // come from b2RayCastInput.   struct b2RayCastOutput   {       b2Vec2 normal;       float32 fraction;   };```
If the ray does intersect the shape, b2Fixture::RayCast will return true and we can look in the output struct to find the actual fraction of the intersect point, and the normal of the fixture 'surface' at that point: ### Example

To try out this very handy function, let's set up a scene with a fenced area and some shapes floating inside in a zero-gravity environment. By now you should be getting used to this one, so we'll make the walls as edges instead of boxes just to spice things up.
 ```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 45 46 47 ``` ```    FooTest() {         //a static body       b2BodyDef myBodyDef;       myBodyDef.type = b2_staticBody;       myBodyDef.position.Set(0, 0);       b2Body* staticBody = m_world->CreateBody(&myBodyDef);         //shape definition       b2PolygonShape polygonShape;           //fixture definition       b2FixtureDef myFixtureDef;       myFixtureDef.shape = &polygonShape;             //add four walls to the static body       b2Vec2 bl(-20, 0);       b2Vec2 br( 20, 0);       b2Vec2 tl(-20,40);       b2Vec2 tr( 20,40);       polygonShape.SetAsEdge( bl, br ); //ground       staticBody->CreateFixture(&myFixtureDef);       polygonShape.SetAsEdge( tl, tr);//ceiling       staticBody->CreateFixture(&myFixtureDef);       polygonShape.SetAsEdge( bl, tl );//left wall       staticBody->CreateFixture(&myFixtureDef);       polygonShape.SetAsEdge( br, tr );//right wall       staticBody->CreateFixture(&myFixtureDef);         myBodyDef.type = b2_dynamicBody;       myBodyDef.position.Set(0,20);       polygonShape.SetAsBox(2,2);       myFixtureDef.density = 1;       for (int i = 0; i < 5; i++)           m_world->CreateBody(&myBodyDef)->CreateFixture(&myFixtureDef);         //circles       b2CircleShape circleShape;       circleShape.m_radius = 2;       myFixtureDef.shape = &circleShape;       for (int i = 0; i < 5; i++)           m_world->CreateBody(&myBodyDef)->CreateFixture(&myFixtureDef);         //turn gravity off       m_world->SetGravity( b2Vec2(0,0) );       }``` Now we need a ray to cast against these shapes. Let's make a ray starting from the center of the screen and going outward, and rotating slowly around. The only state we need to keep for this is the current angle, so instead of making a special class for it, we'll just keep a variable at global scope.
 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ``` ```  //at global scope   float currentRayAngle = 0;     //in Step() function   currentRayAngle += 360 / 20.0 / 60.0 * DEGTORAD; //one revolution every 20 seconds     //calculate points of ray   float rayLength = 25; //long enough to hit the walls   b2Vec2 p1( 0, 20 ); //center of scene   b2Vec2 p2 = p1 + rayLength * b2Vec2( sinf(currentRayAngle), cosf(currentRayAngle) );     //draw a line   glColor3f(1,1,1); //white   glBegin(GL_LINES);   glVertex2f( p1.x, p1.y );   glVertex2f( p2.x, p2.y );   glEnd();``` You should now see a white line circling the scene. Now we just need to use the RayCast function to get the distance to the closest intersected shape, and draw the line at that length. We will check every fixture of every shape, which is not the best way to do this, but will do as an example (see the world querying topic for a more efficient method). It also means we can take a look at how you can iterate over the contents of the world:
 ```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 ``` ```  //in Step() function, continuing on from section above         //set up input       b2RayCastInput input;       input.p1 = p1;       input.p2 = p2;       input.maxFraction = 1;         //check every fixture of every body to find closest       float closestFraction = 1; //start with end of line as p2       b2Vec2 intersectionNormal(0,0);       for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) {           for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) {                 b2RayCastOutput output;               if ( ! f->RayCast( &output, input ) )                   continue;               if ( output.fraction < closestFraction ) {                   closestFraction = output.fraction;                   intersectionNormal = output.normal;               }                       }       }         b2Vec2 intersectionPoint = p1 + closestFraction * (p2 - p1);         //draw a line       glColor3f(1,1,1); //white       glBegin(GL_LINES);       glVertex2f( p1.x, p1.y );       glVertex2f( intersectionPoint.x, intersectionPoint.y );       glEnd();             //draw a point at the intersection point       glPointSize(5);       glBegin(GL_POINTS);       glVertex2f( intersectionPoint.x, intersectionPoint.y );       glEnd();```
You might notice that now we are drawing two lines on top of each other... for clarity, delete the first one and you should get this result: Well that's about all there is to finding the intersection point. We can use the normal in the output struct for some interesting stuff though, so let's try it out. First, we'll simply render the normal to see what it looks like:
 ```1 2 3 4 5 6 7 ``` ```      //draw intersection normal       b2Vec2 normalEnd = intersectionPoint + intersectionNormal;       glColor3f(0,1,0); //green       glBegin(GL_LINES);       glVertex2f( intersectionPoint.x, intersectionPoint.y );       glVertex2f( normalEnd.x, normalEnd.y );       glEnd();``` And for a grand finale, we can put the raycasting code into its own function and call it recursively to reflect the ray off the intersected fixtures until it runs out. This is not really anything to do with Box2D, I just think it's neat :) Here is the code:
 ```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 45 ``` ```  //new function for FooTest class   void drawReflectedRay( b2Vec2 p1, b2Vec2 p2 )   {       //set up input       b2RayCastInput input;       input.p1 = p1;       input.p2 = p2;       input.maxFraction = 1;         //check every fixture of every body to find closest       float closestFraction = 1; //start with end of line as p2       b2Vec2 intersectionNormal(0,0);       for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) {           for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) {                 b2RayCastOutput output;               if ( ! f->RayCast( &output, input ) )                   continue;               if ( output.fraction < closestFraction ) {                   closestFraction = output.fraction;                   intersectionNormal = output.normal;               }           }       }       b2Vec2 intersectionPoint = p1 + closestFraction * (p2 - p1);         //draw this part of the ray       glBegin(GL_LINES);       glVertex2f( p1.x, p1.y );       glVertex2f( intersectionPoint.x, intersectionPoint.y );       glEnd();         if ( closestFraction == 1 )           return; //ray hit nothing so we can finish here       if ( closestFraction == 0 )           return;         //still some ray left to reflect       b2Vec2 remainingRay = (p2 - intersectionPoint);       b2Vec2 projectedOntoNormal = b2Dot(remainingRay, intersectionNormal) * intersectionNormal;       b2Vec2 nextp2 = p2 - 2 * projectedOntoNormal;         //recurse       drawReflectedRay(intersectionPoint, nextp2);   }```
... and then inside Step() you would just have:
 ```1 2 3 4 5 6 7 ``` ```      //calculate points of ray       float rayLength = 25;       b2Vec2 p1( 0, 20 ); //center of scene       b2Vec2 p2 = p1 + rayLength * b2Vec2( sinf(currentRayAngle), cosf(currentRayAngle) );         glColor3f(1,1,1); //white       drawReflectedRay(p1, p2);```