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 directionthe 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 rowcolumn 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.