# Need someone to check C++ - C#/XNA code port

This topic is 3107 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I'm currently working through Mat Buckland's book "Programming game AI by example", more specifically, chapter 4, creating a simple football game. While the book used C++ I am using C#/XNA. I'm trying to debug why exactly my agents are behaving like headless chickens instead of world class footballers, and have come up with the possibility that my problems are something to do with a specific function being ported wrong. Please could someone look over my port and tell me if ive made any mistake along the way: Mat Buckland's functions
[source language="cpp"]
{
Vector2D toTarget = Vec2DNormalize(target - m_vPosition);

//some compilers lose acurracy so the value is clamped to ensure it
//remains valid for the acos
Clamp(dot, -1, 1);

//first determine the angle between the heading vector and the target
double angle = acos(dot);

//return true if the player is facing the target
if (angle < 0.00001) return true;

//clamp the amount to turn to the max turn rate
if (angle > m_dMaxTurnRate) angle = m_dMaxTurnRate;

//The next few lines use a rotation matrix to rotate the player's heading
//vector accordingly
C2DMatrix RotationMatrix;

//notice how the direction of rotation has to be determined when creating
//the rotation matrix
RotationMatrix.TransformVector2Ds(m_vVelocity);

//finally recreate m_vSide

return false;
}

enum {clockwise = 1, anticlockwise = -1};

inline int Vector2D::Sign(const Vector2D& v2)const
{
if (y*v2.x > x*v2.y)
{
return anticlockwise;
}
else
{
return clockwise;
}
}

inline void C2DMatrix::TransformVector2Ds(Vector2D &vPoint)
{

double tempX =(m_Matrix._11*vPoint.x) + (m_Matrix._21*vPoint.y) + (m_Matrix._31);

double tempY = (m_Matrix._12*vPoint.x) + (m_Matrix._22*vPoint.y) + (m_Matrix._32);

vPoint.x = tempX;

vPoint.y = tempY;
}

inline Vector2D Vector2D::Perp()const
{
return Vector2D(-y, x);
}


My port
[source language="C#"]
{
Vector2 toTarget = Vector2.Normalize(target - Position);

float dot;
Vector2.Dot(ref Heading, ref toTarget, out dot);

// Clamp to ensure we keep accuracy
MathHelper.Clamp(dot, -1.0f, 1.0f);

// Determine the angle between the heading vector and the target
float angle = (float)Math.Acos(dot);

//return true if the player is facing the target
if (angle < 0.00001f) return true;

// clamp the amount to turn to the max turn rate
if (angle > MaxTurnRate) angle = MaxTurnRate;

Matrix rotationMatrix =

rotationMatrix.TransformVector2(ref Velocity);

return false;
}

/// <summary>
/// Returns +1 if value is clockwise of this vector, -1 if anticlockwise (Y axis pointing down, X axis to right)
/// </summary>
/// <param name="param"></param>
/// <param name="value"></param>
/// <returns></returns>
public static int Sign(this Vector2 param, Vector2 value)
{
if (param.Y * value.X > param.X * value.Y)
{
return -1;
}

return 1;
}

/// <summary>
/// Transforms a vector by a matrix
/// </summary>
/// <param name="param"></param>
/// <param name="value"></param>
public static void TransformVector2(this Matrix param, ref Vector2 value)
{
value.X = (param.M11 * value.X) + (param.M21 * value.Y) + param.M31;
value.Y = (param.M12 * value.X) + (param.M22 * value.Y) + param.M32;
}

/// <summary>
/// Returns the vector perpendicular to the param
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public static Vector2 Perpendicular(this Vector2 param)
{
return new Vector2(-param.Y, param.X);
}


I'm aware this is probably a long shot, but eliminating this as a root cause of problems will go a long way to helping me debug this. Thanks for the help, Scott

##### Share on other sites
In TransformVector2, you still need the temp variables. Right now you are changing X and then using the new value to calculate Y.

##### Share on other sites
Thanks, how did I miss that one, well thats made a slight improvement, still headles chicken tho :D

##### Share on other sites
This doesn't answer your question, but it may help later - avoid arccosine. You correctly clamp it before use, but it's almost always possible to code more efficiently and accurately without arc functions, though it make take a little more algebra. arccosine is fine in a math textbook. In the real world on finite state machines, it usually leads to grief.