# Matrix rotation of a rectangle to “face” a given point in 2d

Suppose you have a rectangle centered at point (0, 0) and now I want to rotate it such that it is facing the point (100, 100), how would I do this purely with matrix math?

To give some more specifics I am using javascript and canvas and I may have something like this:

var position = {x : 0, y: 0 };
var destination = { x : 100, y: 100 };
var transform = Matrix.identity();

this.update = function(state) {

// update transform to rotate to face destination

};

this.draw = function(ctx) {
ctx.save();
ctx.transform(transform); // a helper that just calls setTransform()
ctx.beginPath();
ctx.rect(-5, -5, 10, 10);
ctx.fillStyle = 'Blue';
ctx.fill();
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
}


Feel free to assume any matrix function you need is available.

• Not sure what you mean by facing since you are doing this in 2d. Do you mean you want a corner to point to 10,10, or you want to skew the rectangle in a way that 0,0 on the rect is facing 10,10? Assuming z is locked at 0 as well then? – Loktar Mar 30 '12 at 16:19
• Whatever way is eaiser to explain I think. I was picturing the identity matrix and identity vector to essentially be the direction the rectangle was "facing" in the start state... but basically I want the top side of the rectangle to be considered the direction it is facing. – justin.m.chase Mar 30 '12 at 16:27
• Sounds like you need to construct a lookat matrix considering the rectangle to be the camera. – chaosTechnician Mar 30 '12 at 16:32
• Oh yes that looks good! I'm assuming the second part of the formula is the new matrix? The formatting there is pretty unfortunate. – justin.m.chase Mar 30 '12 at 17:09
• Justin, your question is not a 2D problem. You have a facing-vector that does not lie in the 2D plane, it points out of it, so you already deal with 3D. Given the 2D constraint, the entire question does not make much sense as it stands, as @Loktar already mentioned. Its actually a 3D problem, so welcome to 3D :) – Maik Semder Mar 30 '12 at 18:23

Here's my first take on it:

Assuming you want the top edge of the rectangle to be the edge that sets the "facing direction" as per your comment, and that would be considered your identity direction (0, -1) or zero angle in 'JustinSpace', rotating the rect so that that edge faces 100,100 would in effect be a 135 degree rotation clockwise. Most Math libraries think of 1,0 as being the identity direction (or 0 angle) requiring a 90 deg shift of the angle to place it into 'JustinSpace'.

A matrix that rotates something 135 deg clockwise on a 2d XY plane looks like this:

float angle = Math.Atan2(100,100) + Math.Atan2(-1, 0); // 45 deg + 90 deg

//RH coordinate Row Major system
Matrix m = Matrix.Identity();
m.11 = m.22 = cos(angle);
m.12 = sin(angle);
m.21 = -sin(angle);

//for column major
//m.Transpose()


If eBusiness' answer works however, I would use it as linear algebra is almost always favorable over trig in game dev.

• Are you sure that angle shouldn't be Math.Atan2(100,100) - Math.Atan2(-1, 0) = 45 deg - 180 deg = -135 deg = 135 deg clockwise? – aaaaaaaaaaaa Mar 30 '12 at 19:50
• very possible, should be tried both ways to make sure... thanks. – Steve H Mar 30 '12 at 20:17
• Thanks a ton, this was almost exactly what I needed. I just submitted an edit to your answer with the actually working function for future reference. I will accept this as the answer. – justin.m.chase Mar 30 '12 at 20:18
• @eBusiness, Actually, not sure where you get the 180 from. Atan2(-1,0) returns the angle of vector 0,-1. Atan2 takes the Y component as the first arg... – Steve H Mar 30 '12 at 20:19
• @Justin, try it with a rect where w != h just to make sure it is rotating the correct direction you want. If I have the rotation going ccw instead of cw, a square like your sample would mask that prob. – Steve H Mar 30 '12 at 20:24

If I got my maths right in order to rotate from facing A to facing B you can use the matrix:

 [ A1*B1+A2*B2   A2*B1-A1*B2 ]
[ A1*B2-A2*B1   A1*B1+A2*B2 ]
_______________________________

|A|*|B|