1

I have the x and y coordinates, and the rotation of a UIImageView that I need to place on its original position. The coordinates correspond to the ones of the view once it had been rotated.

The problem that I have found is that if I initialize the view with the given x and y, and perform the rotation afterwards, the final position is not correct, because the order in which the transformations were applied was not correct:

float x, y, w, h; // These values are given 

UIImageView *imageView = [[UIImageView alloc] init];

// Apply transformations
imageView.frame = CGRectMake(x, y, w, h);
imageView.transform = CGAffineTransformRotate(imageView.transform, a.rotation);

If I try to use the x and y to translate the view once it has been rotated, then the final x and y are completely wrong:

float x, y, w, h; // These values are given 

UIImageView *imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(0, 0, w, h);

// Apply transformations
imageView.transform = CGAffineTransformTranslate(imageView.transform, x, y);
imageView.transform = CGAffineTransformRotate(imageView.transform, a.rotation);

I have tried updating the center of the view after applying the rotation with incorrect results too.

I am looking for some advice or tips on how to deal with this in order to achieve the result that I need.

Thanks in advanced!

ojcar
  • 118
  • 1
  • 7

2 Answers2

1

I'm using this C function to make rotation transform around center:

static inline CGAffineTransform CGAffineTransformMakeRotationAroundCenter(double width, double height, double rad) {
    CGAffineTransform t = CGAffineTransformMakeTranslation(height/2, width/2);
    t = CGAffineTransformRotate(t, rad);
    t = CGAffineTransformTranslate(t, -width/2, -height/2);

    return t;
}

You need to specify width, height and angle in radians.

Does this solve you problem?

Eugene
  • 93
  • 1
  • 7
  • I am sorry Darius, but I don't see how this can help in what I was trying to do. I solved it calculating the offset in the Y axis after rotating the view, and applying it to the center of the frame once transformed. Maybe if you could explain a little bit further the solution could be simpler. – ojcar Aug 13 '14 at 14:31
1

I was able to fix this by calculating the offset in the Y axis between the original Y position where the frame should be, and the origin of the transformed view.

The functions provided in this answer for a similar question provide a way to calculate the new origin of the frame by creating a point with the minimum X and Y among all the new corners:

-(CGPoint)frameOriginAfterTransform 
{
    CGPoint newTopLeft = [self newTopLeft];
    CGPoint newTopRight = [self newTopRight];
    CGPoint newBottomLeft = [self newBottomLeft];
    CGPoint newBottomRight = [self newBottomRight];

    CGFloat minX = fminf(newTopLeft.x, fminf(newTopRight.x, fminf(newBottomLeft.x, newBottomRight.x)));
    CGFloat minY = fminf(newTopLeft.y, fminf(newTopRight.y, fminf(newBottomLeft.y, newBottomRight.y)));

    return CGPointMake(minX, minY);
}

Afterwards I calculated the offset in the Y axis and applied it to the center of the transformed view:

// Adjust Y after rotating to compensate offset
CGPoint center = imageView.center;
CGPoint newOrigin = [imageView frameOriginAfterTransform]; // Frame origin calculated after transform
CGPoint newCenter = CGPointZero;
newCenter.x = center.x;
newCenter.y = center.y + (y - newOrigin.y);
imageView.center = newCenter;

For some reason the offset is only affecting the Y axis, although at first I thought it was going to affect both X and Y.

Hope this helps!

ojcar
  • 118
  • 1
  • 7
  • This is the post containing the helper methods mentioned above: https://stackoverflow.com/questions/19523487/find-frame-coordinates-after-uiview-transform-is-applied-cgaffinetransform – Nikolai Sander Jun 24 '22 at 18:33