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][1]. 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. [1]: https://gamedev.stackexchange.com/a/89838/39518