Looking for help understanding why this World to Local Space function works.

I'm working my way through Buckland's Programming Game AI By Example The following function is used in the book to convert a point from world space to an agent's local coordinate space (its i hat and j hat are AgentHeading and AgentSide respectively)

    inline Vector2D PointToLocalSpace(const Vector2D &point,
                             Vector2D &AgentHeading,
                             Vector2D &AgentSide,
                              Vector2D &AgentPosition)

    //make a copy of the point
  Vector2D TransPoint = point;

  //create a transformation matrix
    C2DMatrix matTransform;

  double Tx = -AgentPosition.Dot(AgentHeading);
  double Ty = -AgentPosition.Dot(AgentSide);

  //create the transformation matrix
  matTransform._11(AgentHeading.x); matTransform._12(AgentSide.x);
  matTransform._21(AgentHeading.y); matTransform._22(AgentSide.y);
  matTransform._31(Tx);           matTransform._32(Ty);

  //now transform the vertices

  return TransPoint;

I've been learning about vectors and matrices for the last three weeks and still I'm having a lot of trouble understanding why this works in terms of vectors and matrices. What is the reason for using a a dot product in the translation coordinates? Why is it the dot product of the agent's position and its heading? What does this dot product correspond to geometrically?

Why not just translate by the Agent's position?

Are there any simpler ways of representing this algorithm?


This is a vector projection. Dotting a vector like AgentPosition with a unit direction vector like AgentHeading or AgentSide gives you the signed length of the component of that vector parallel to that direction.

Doing it with each perpendicular axis direction lets you express a point from one coordinate system in a new coordinate system with those direction vectors as its basis.

So AgentPosition.Dot(AgentHeading) answers "how far is the agent from the origin, along the heading direction?" and AgentPosition.Dot(AgentSide) does the same for the side direction. Negating these flips the question: "how far is the origin from the agent, along this direction?"

Combined, Tx and Ty now hold the position of the world origin, from the perspective of the agent's local coordinate system, where +x is its heading, and +y is its side.

A simpler version of this algorithm (assuming the heading and side vectors are perpendicular unit vectors, so no scaling or shearing) would be:

inline Vector2D PointToLocalSpace(const Vector2D &point,
                             Vector2D &AgentHeading,
                             Vector2D &AgentSide,
                              Vector2D &AgentPosition)
  // Get the world space vector from the agent to the point.
  Vector2D offset = point.Subtract(AgentPosition);

  // Project this offset onto our heading & side directions to put it in local space.
  Vector2D local;
  local.x = offset.Dot(AgentHeading);
  local.y = offset.Dot(AgentSide);

  return local;

If you expand out the math, you'll find this is equivalent to the original function:

local.x = offset.x * AgentHeading.x + offset.y * AgentHeading.y
        = (point.x - AgentPosition.x) * AgentHeading.x + (point.y - AgentPosition.y) * AgentHeading.y
        = (point.x * AgentHeading.x + point.y * AgentHeading.y) + -1 * (AgentPosition.x * AgentHeading.x + AgentPosition.y * AgentHeading.y)
        = point.Dot(AgentHeading) + -1 * AgentPosition.Dot(AgentHeading)
        = Result of multiplying the point with the first column of matTransform

We've just done the subtraction first, before we multiplied by the heading/side. In the matrix version, the subtraction happens after the multiplication by heading/side, so we need to "pre-multiply" the contribution of the heading & side vectors into it, to accomplish the same outcome.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.