# How do I rotate a matrix transformation with a centered origin?

This is actually something I'm doing in Objective-C programming, but since it's very math-oriented I thought I'd post it here.

I was reading up on linear transformations: http://en.wikipedia.org/wiki/Matrix_(mathematics)

Basically I need to rotate a shape around its center. With my current implementation, the rotation is done using the top left as its origin. Here's a screenshot:

Here's the code I'm using to create each x,y coordinate:


CGFloat angle = 0.261799; // (15 degrees)
CGFloat xr = x1 * cosf(angle) + y1 * -sinf(angle) + tx;
CGFloat yr = x1 * sinf(angle) + y1 * cosf(angle) + ty;


I realize there are functions (CGAffineTransformRotate, etc) in Objective-C that do this for me, but since I'm not using a UIView, I need to do it manually. Plus, it would be nice to know. :)

So when I plug in 35.0 for tx and -35.0 for ty, (numbers I just found that seemed to work, through trial and error) here is what I get:

That's what I want! Now I just need some way to figure out these tx and ty translation values to center the shape's origin, based on the given angle, width or height values. (I'm also seeing different results when setting tx and ty if the original x,y coordinates of the shape are different.)

Any help would be much appreciated. Thanks!

-
Mike, thanks for correcting my tags - any ideas on a solution? –  taber Sep 6 '11 at 3:24
You know the point you're rotating everything else about, yes? Translate everything so that the rotation point is the origin, apply the rotations, and then undo the translation. –  Guess who it is. Sep 6 '11 at 3:42
Thanks for the suggestion - that's how I'd do it when using CGAffineTransformRotate/CGAffineTransformTranslate, but because of other app limitations this is actually being done inside drawRect, which doesn't really have control over the parent view's location. I'm pretty sure CGAffineTransformTranslate just adjusts the tx & ty values in the tranform matrix anyway, hmm. I'll try playing with that though. –  taber Sep 6 '11 at 3:55

Let xc, yc be the coordinates of the center of the rectangle.

1. Translate your points such that the center is the new origin:

xt = x1 - xc;
yt = y1 - yc;

2. Rotate around the origin by the angle a:

c = cos(a); // compute trig. functions only once
s = sin(a);
xr = xt * c - yt * s;
yr = xt * s + yt * c;

3. Translate points back:

x2 = xr + xc;
y2 = yr + yc;


If you do this for all 4 corners of the rectangle and then draw lines between the transformed corners, you get the rotated rectangle. The rotation angle $a$ is measured from the x-axis ($0$) to to the y-axis ($\pi/2$). In 2D graphic libraries the x-axis goes to the right and the y-axis goes down, such that the angle $+35^\circ$ corresponds to your figure.

-

As Jiri pointed out your problem is easy to solve once you have found the "center of gravity". It can be quite tricky for complicated examples but here what you have to do is:

• Fix the origin of the frame
• Draw the shape
• Find the coordinates of the center-of-gravity
• Use this coordinate to translate your control points (e.g. corners for rectangle) to the origin
• Perform the rotation on the control points and translate back.

Here is a 3D-Computer graphics link and some nice code that popped up in a quick search.

-