You Are Here Home > iPhone SDK: CGAffineTransformInvert and iPhone 4

iPhone SDK: CGAffineTransformInvert and iPhone 4

So if you tried a piece of code like:

CGAffineTransform t0 = CGContextGetCTM(context);
t0 = CGAffineTransformInvert(t0);
CGContextConcatCTM(context, t0);

You know that in iPhone 4, your drawings will be smaller, and if you don’t use this bit of code, your origin is not in the lower left corner but in top left.

The reason for this is that t0 is a transformation matrix, Core Graphics will multiply every point by this matrix to find it’s location on the screen.

Read more about this matrix here:

http://iphonedevelopment.blogspot.com/2008/10/demystifying-cgaffinetransform.html

This matrix is a 3×3 matrix like this:

| a  b  0 |
| c  d  0 |
| tx ty 1 |

Now if print these before the call to CGAffineTransformInvert values to console, you will see this for iPhone 4:
a: 2.000000 – b: 0.000000 – c: 0.000000 – d: -2.000000 – tx: 0.000000 – ty: 960.000000

And after:
a: 0.500000 – b: 0.000000 – c: 0.000000 – d: -0.500000 – tx: -0.000000 – ty: 480.000000

You can see that a and d are used to scale the shapes you draw and CGAffineTransformInvert changes these values to a smaller value since iPhone 4 has much more pixels in it’s display and is capable of better resolutions.

Here are the values for iPhone 3:
a: 1.000000 – b: 0.000000 – c: 0.000000 – d: -1.000000 – tx: 0.000000 – ty: 480.000000

And after the call to CGAffineTransformInvert:
a: 1.000000 – b: 0.000000 – c: 0.000000 – d: -1.000000 – tx: -0.000000 – ty: 480.000000

The Solution

(Or at least I’m using this until I find a better solution) Add this to your code:

CGAffineTransform t0 = CGContextGetCTM(context);
 
    CGFloat xScaleFactor = t0.a > 0 ? t0.a : -t0.a;
    CGFloat yScaleFactor = t0.d > 0 ? t0.d : -t0.d;
    t0 = CGAffineTransformInvert(t0);
    if (xScaleFactor != 1.0 || yScaleFactor != 1.0)
        t0 = CGAffineTransformScale(t0, xScaleFactor, yScaleFactor);
    CGContextConcatCTM(context, t0);

This code will check the value of t0.a and t0.d in the matrix and if it’s not equal to one, it scales the matrix to match the original values. It also ensures that the xScaleFactor and yScaleFactor values are positive.

Again, this looks nasty but works, if there is a better way, please let me know…

iPhone SDK: CGAffineTransformInvert and iPhone 4
Filed under: iPhone SDK   Posted by: Hamid

1 Comment »

  1.  

    So this is only necessary in cases where you are trying to move the origin to the bottom-left, right?

    Comment

     

RSS feed for comments on this post. TrackBack URL

Leave a comment