// find the vector from present position to next waypoint
D3DXVECTOR3 vec = m_lorryPath->GetWaypoint( m_lorryWaypoint ) - m_lorry->GetTranslation();
float presentHeading = m_lorry->GetHeading();
float goalHeading = atan( vec.z/vec.x );
D3DXVec3Normalize( &vec, &vec );
m_lorry->SetTranslation( m_lorry->GetTranslation() + vec * g_timeDelta * LORRY_SPEED );
// turn
m_lorry->Yaw( ( presentHeading - goalHeading ) * g_timeDelta * LORRY_TURN_RATE);
// Has it reached its waypoint?
if ( m_lorryPath->CheckWaypoint( m_lorry->GetTranslation(), m_lorryWaypoint ) )
m_lorryWaypoint = m_lorryPath->NextWaypoint( m_lorryWaypoint, true );
Getting a vehicle to drive towards a point.
Hi,
I have some simple vehicles driving about in the background of my app. They follow a sequence of waypoints.
My problem is in the way I am getting the vehicles to decide if they need to turn left or right. Sometimes, due to the heading, they will turn all the way round left when they only needed to turn right, plus sometimes they think drive backwards! :)
Heres my crude code:
Obviously, its to do with atan returning a value from -PI to PI, or -180deg to 180deg.
If the truck is on 175deg heading and needs to turn to 185deg, it will turn left 350deg.
Can anyone suggest a more reliable way of doing this?
Thanks
Simon
my guess is you need to calibrate the atan() result a bit, I was working on a similar (but 2D) game and I remember, I used a slightly modificated atan() calcs:
possibly not accurate enough, as I write from memory, but I was having exactly the same vehicle turning problems.
maybe you should ask in the math board
if (vec.x > 0) goalHeading = atan(vec.z/vec.x) - 2*PI else if ( vec.x < 0 ) goalHeading = atan(vec.z / vec.x) + 2*PI else goalHeading = 2 * atan( vec.x > 0 ? -1.0f : 1.0f );
possibly not accurate enough, as I write from memory, but I was having exactly the same vehicle turning problems.
maybe you should ask in the math board
If you use atan2() instead of atan() then it should give you a value in the correct quadrant, i.e. an angle between o and 360 degrees. Then you just need to work out which way to turn.
float goalHeading = atan2f( vec.z/vec.x );
float headingDifference = presentHeading - goalHeading;
if(headingDifference > PI)
headingDifference -= (PI * 2.f);
else if(headingDifference Yaw(headingDifference * g_timeDelta * LORRY_TURN_RATE);
...this is untested by the way...
float goalHeading = atan2f( vec.z/vec.x );
float headingDifference = presentHeading - goalHeading;
if(headingDifference > PI)
headingDifference -= (PI * 2.f);
else if(headingDifference Yaw(headingDifference * g_timeDelta * LORRY_TURN_RATE);
...this is untested by the way...
Whoops sorry - I forgot the code thingy
float goalHeading = atan2f( vec.z/vec.x );float headingDifference = presentHeading - goalHeading;if(headingDifference > PI) headingDifference -= (PI * 2.f);else if(headingDifference < -PI) headingDifference += (PI * 2.f);m_lorry->Yaw(headingDifference * g_timeDelta * LORRY_TURN_RATE);
If you measure directions in the Cars Local Coordinate System
as opposed to a world compass heading angle
then you would not have this issue
plus it makes the car logic simpler and more encapsulated
Id reccomend tossing out angles entirely
just use the vector from the car to the waypoint, and internally to the car object evalute that...
as opposed to a world compass heading angle
then you would not have this issue
plus it makes the car logic simpler and more encapsulated
Id reccomend tossing out angles entirely
just use the vector from the car to the waypoint, and internally to the car object evalute that...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement