1
votes

Working with box2d and cocos2d, I've calculated two vectors:

  • one is the vector pointing in the direction the car is travelling. (center of the vehicle to it's north point).
  • two is the vector pointing in the direction of the target. (center to the vehicle to the target center.)

I need to rotate the vehicle to also point in the direction of the target. This is done by setting the vehicle's steering either 90 degrees to turn right or -90 to turn left.

At the moment i'm querying the box2d body of the vehicle for its angle, then calculating the angle of the target direction vector using:

if(vector.y == 0){ vector.y = 0.000001f; }
float baseRadians = atan(vector.x/vector.y);
if(vector.y < 0){ baseRadians += PI_CONSTANT; } //Adjust for -Y
return -1 * baseRadians;

The following is crude and where I need help...!

I then compare the angle of the vehicle against the angle returned from the direction vector and set the steering as follows:

if(vehicleAngle < targetAngle)
        {
            steeringInput = -90.0;    
        }
        else if(vehicleAngle > targetAngle)
        {
            steeringInput = 90.0;    
        }
        else
        {
            steeringInput = 0.0;     
        }

The problem is two fold:

  • The target angle jumps from -4.71 to 1.57 radians, causing the vehicle to switch to the wrong direction
  • The vehicle angle is continous and keeps increasing rather than staying within a range.

Is there a way to get both the target vector and the vehicle angle in a set range where, for example, if the target angle is 0-360 and the van angle is 0-360, i can then compare them accurately?

Any other way to do this...? Any help appreciated!

2
okay, fixed the continous angle problem by getting the angle of the vehicle by calculating the angle of direction vector. Still stuck on the range problem though? - Ray A

2 Answers

0
votes

Use atan2 instead of atan in your code. It gets the angle from one object to another.

0
votes

Using the atan2f function instead I managed to get the vehicle vector angle and target vector angle.

my new implementation is as follows:

 //get the direction the vehicle is facing and the direction the target is facing


CGPoint vehicleDirectionVector = ccpNormalize(ccpSub(ccp(vehicleBonnetTip.x*PTM_RATIO, vehicleBonnetTip.y*PTM_RATIO), ccp(vehicleCenter.x*PTM_RATIO, vehicleCenter.y*PTM_RATIO)));

CGPoint targetDirectionVector = ccpNormalize(ccpSub(ccp(origTarget.x, origTarget.y), ccp(vehicleCenter.x*PTM_RATIO, vehicleCenter.y*PTM_RATIO)));


vehicleAngle = atan2f(vehicleDirectionVector.x,vehicleDirectionVector.y);
targetAngle = atan2f(targetDirectionVector.x,targetDirectionVector.y);

if ( targetAngle < -M_PI / 2 && vehicleAngle > M_PI / 2 ) targetAngle += M_PI * 2;
if ( targetAngle > M_PI / 2 && vehicleAngle < -M_PI / 2 ) targetAngle -= M_PI * 2;

if ( vehicleAngle < -M_PI / 2 && targetAngle > M_PI / 2 ) vehicleAngle += M_PI * 2;
if ( vehicleAngle > M_PI / 2 && targetAngle < -M_PI / 2 ) vehicleAngle -= M_PI * 2;

CCLOG(@"vehicle angle is %f, target angle is %f", vehicleAngle, targetAngle);

Then to set my steering, crudely (i'm still working on this one..) i do:

if(vehicleAngle < targetAngle)
        {
            steeringDegrees = 90.0;    
        }
        else if(vehicleAngle > targetAngle)
        {
            steeringDegrees = -90.0;     
        }
        else
        {
            steeringDegrees = 0.0;     
        }