Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CGRectApplyAffineTransform then CGAffineTransformInvert doesn't return to original position

This does not seem possible and I'm sure there's a simple solution but I cannot work it out. My High School matrix math is a bit rusty :)

I'm building a CGAffineTransform to do translation-rotation-translation of a CGRect and then trying to use the inverse CGAffineTransformInvert to return to the original location. But it doesn't. I've managed to reduce it to this:

//  start building the transform...
//  translate so (0,0) is at centre of image
CGAffineTransform affine = CGAffineTransformMakeTranslation(-100, -100);

//  add a rotate
affine = CGAffineTransformConcat(affine, CGAffineTransformMakeRotation(M_PI/4));

//  get the inverse
CGAffineTransform inverseAffine = CGAffineTransformInvert(affine);

//  now test this: pick a starting CGRect
CGRect start = CGRectMake(50, 40, 10, 20);

// use my CGAffineTransform to move "start" to "midpoint"
CGRect midpoint = CGRectApplyAffineTransform(start, affine);

//  use the inverse to move "midpoint" to "finish"
CGRect finish = CGRectApplyAffineTransform(midpoint, inverseAffine);

//  what did we get
NSLog(@"start    %5.1f %5.1f %5.1f %5.1f", start.origin.x, start.origin.y, start.size.width, start.size.height);
NSLog(@"midpoint %5.1f %5.1f %5.1f %5.1f", midpoint.origin.x, midpoint.origin.y, midpoint.size.width, midpoint.size.height);
NSLog(@"finish   %5.1f %5.1f %5.1f %5.1f", finish.origin.x, finish.origin.y, finish.size.width, finish.size.height);

The output looks like this:

2011-09-29 ... start     50.0  40.0  10.0  20.0
2011-09-29 ... midpoint  -7.1 -77.8  21.2  21.2
2011-09-29 ... finish    40.0  35.0  30.0  30.0

Shouldn't the finish rect be the same as the start? Isn't that what CGAffineTransformInvert is supposed to do?

If I do the same thing but with a CGPoint instead of a CGRect it seems to work ok.

like image 450
Steve Rogers Avatar asked Sep 28 '11 15:09

Steve Rogers


1 Answers

Copied from documentation: You can operate on a CGRect structure by calling the function CGRectApplyAffineTransform. This function returns the smallest rectangle that contains the transformed corner points of the rectangle passed to it. If the affine transform that operates on the rectangle performs only scaling and translation operations, the returned rectangle coincides with the rectangle constructed from the four transformed corners.

like image 63
Hitesh Savaliya Avatar answered Oct 13 '22 00:10

Hitesh Savaliya