I've been studying an AI book titled "Programming game AI by Example" by Mat Buckland.
Currently, i'm stuck at Wandering. The book implements the wandering algorithm by creating a wander circle and setting a point to move at random points on the circle circumference. The circle is then projected in front of the agent and a force drives the agent towards the direction of that point, which creates a wandering effect.
I've followed the code in the book but somehow the agent does not move at all. The code is a windows forms project in C# and the agent is represented by a picturebox control.
I created a class called steering and in the constructor, a point is set randomly on the circle. m_vWanderTarget is a vector2D type.
double theta = RandomNumber(0,1) * TwoPi;
//create a vector to a target position on the wander circle
m_vWanderTarget = new Vector2D(m_dWanderRadius * Math.Cos(theta),m_dWanderRadius * Math.Sin(theta));
The main algorithm is contained in the Wander method. The random displacement is added to the target and it is normalised and reprojected back into the wander circle. Then the circle is projected back in front of the agent.
m_dWanderJitter is the max amount of random displacement to add, m_dWanderRadius is the radius of the circle and m_vWanderDistance is the distance the circle is in front of the agent.
double JitterThisTimeSlice = m_dWanderJitter * 0.7;
m_vWanderTarget += new Vector2D(RandomNumber(-1.1,1.1) * JitterThisTimeSlice,
RandomNumber(-1.1,1.1) * JitterThisTimeSlice);
m_vWanderTarget.Normalize();
m_vWanderTarget *= m_dWanderRadius;
Vector2D target = m_vWanderTarget + new Vector2D(m_dWanderDistance, 0);
Vector2D Target = transform.PointToWorldSpace(target,m_pVehicle.GetHeading(),
m_pVehicle.GetSide(),m_pVehicle.GetPos());
return target - m_pVehicle.GetPos();
The method for PointToWorldSpace converts the point from local to world space. AgentHeading is the unit vector representing the agent's direction. AgentSide is the vector perpendicular to AgentHeading while AgentPosition is the location.
public Vector2D PointToWorldSpace(Vector2D point, Vector2D AgentHeading,
Vector2D AgentSide, Vector2D AgentPosition)
{
//make a copy of the point
Vector2D TransPoint = point;
//create a transformation matrix
C2DMatrix matTransform = new C2DMatrix();
//rotate
matTransform.Rotate(ref AgentHeading, ref AgentSide);
//and translate
matTransform.Translate(AgentPosition.GetX(), AgentPosition.GetY());
//now transform the vertices
//applies a 2D transformation matrix to a single Vector
//multiplies the final transformation matrix with the vector
matTransform.TransformVector2Ds(ref TransPoint);
return TransPoint;
}
The code which uses the resulting vector to move the picturebox control is not shown as it worked correctly with other movement algorithms.
I've checked the code with the one in the book for typos but it looks correct.
Is there anything incorrect with the wander code or the transformation code?
:(
I would suggest you to compare with the random behavior showed on that site: www.red3d.com/cwr/steer/Wander.html (by Mr Craig Reynolds).
The computation steps are provided in his article (www.red3d.com/cwr/papers/1999/gdc99steer.html).
To compute, you must follow these steps: 1- compute the change rate vector (your m_vWanderTarget) 2- from previous wander target on the wander circle, apply the change rate vector: this gives you a new target. This new Wander vector must be clamped to the Wander circle. 3- Then when you need to evaluate the speed and direction, you compute the vector between the old and new target and derive the speed and orientation change.