Question

I've read the following, from One step affine transform for rotation around a point?:

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);

However, when I do this the images transformed are all over the map, and rarely over the screen.

I've tried a bit to make a system where it will place images; if you run a loop and place several values, a spiral appears. However, while I might be able to eventually untangle the relationship between a rotation of images and the points I wanted them to rotate about, I wanted to ask for the best solution to "I have an image here; I consider this point to be its center; I want it to be rotated by this amount around its center but not otherwise displaced."

I am trying to make a modified port of http://JonathansCorner.com/ancient-clock/, and right now I am trying to place the hour hand. All attempts to do the song and dance above, and translate it so its center is at the desired center, have failed.

How, for the hands of this clock, can I say "I want the hands in the following rotations" and have them appropriately placed around the center?

--EDIT--

The crucial part of this code, edited in an attempt to use layers in response to a comment, is:

UIImage *hourHandImage = [UIImage imageNamed:@"hour-hand.png"];
UIImageView *hourHandView = [[UIImageView alloc] initWithImage:hourHandImage];
float hourRotation = .5;
hourHandImage = [UIImage imageNamed:@"hour-hand.png"];
hourHandView = [[UIImageView alloc] initWithImage:hourHandImage];
CGAffineTransform transform = CGAffineTransformMakeTranslation(centerX - 21, -centerY - 121);
// transform = CGAffineTransformRotate(transform, hourRotation);
// transform = CGAffineTransformTranslate(transform, 2 * centerX, 2 * centerY);
hourHandView.transform = transform;
hourHandView.layer.anchorPoint = CGPointMake(centerX, centerY);
hourHandView.layer.affineTransform = CGAffineTransformRotate(transform, hourRotation);
[self.view addSubview:hourHandView];

Thanks,

--EDIT--

I now have something pared down; if I follow some of the instructions, I have:

CGAffineTransform transform = CGAffineTransformMakeTranslation(100 -21, 100 -121);
transform = CGAffineTransformRotate(transform, hour / 12.0 * M_PI * 2.0);
transform = CGAffineTransformTranslate(transform, -330, 330);
hourHandView.transform = transform;

I'd like to work on getting those numbers out, but this has an hour of 9:00 correctly displayed.

Thanks for all your help!

Was it helpful?

Solution 2

This line:

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);

moves the image by x, y.

(Note-- you will spin around the control point, whatever you've set that to be)

this line:

transform = CGAffineTransformRotate(transform, a);

rotates it around the control point.

If your control point is in the top left hand corner (the default), it will spin around the top lefthand corner.

You need to set this:

[self layer].anchorPoint = CGPointMake(0.5, 0.5);

to get it to spin around the center of the layer.

OTHER TIPS

A rotation is always done around (0,0).

To translate around a point you FIRST need to translate the rotate point to (0,0) and then rotate it, and then translate it back.

So it should be:

// cx, cy is center of screen
// move (cx,cy) to (0,0)  
CGAffineTransform transform = CGAffineTransformMakeTranslation(-cx, -cy);

// roate around (0,0)  
transform = CGAffineTransformRotate(transform, angleRadians);

// mov e (0,0) back to (cx,cy)  
transform = CGAffineTransformTranslate(transform,cx,cy);
hourImageView.layer.anchorPoint = CGPointMake(0.5f, 0.9f);
CGFloat angle = hour / 12.0 * M_PI * 2.0;
hourHand.transform = CGAffineTransformMakeRotation(angle);

Swift 5 version from Alex's answer

A rotation is always done around (0,0).

To translate around a point you FIRST need to translate the rotate point to (0,0) and then rotate it, and then translate it back.

So it should be:

// centerX, centerY is center of screen
// move (centerX,centerY) to (0,0)  
var myTransform = CGAffineTransform(translationX: -centerX, y: -centerY)

// rotate around (0,0)  
myTransform = myTransform.concatenating(CGAffineTransform(rotationAngle: angleInRadians))

// move (0,0) back to (cx,cy)  
myTransform = myTransform.concatenating(CGAffineTransform(translationX: centerX, y: centerY))

myView.transform = myTransform
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top