views:

721

answers:

2

My usercase is an iphone application where I do an animation on the scale, rotation and translation of an image.

So, I concat everything and feed it to the transform property, but there is one problem:

Since my images vary in size, it is a problem to position them correctly. I'm used to an inverted y axis coordinate system, so I want my image to positioned exactly at 60 pixels in the y axis.

So, how do I change from the original cartesian y axis to an inverted y axis point of view?

A: 

For every y ordinate, y = top-y, where top is the y ordinate of the top of the bounding box you are drawing in.

Shane MacLaughlin
+3  A: 

As smacl points out, the easiest way to do this is to shift your origin to the bottom-left of the screen by using (screenheight - viewheight - y) instead of y in the origins of your views.

However, you can flip the coordinate system of your main view's layers using a CATransform3D. I do this so that I can share the same Core Animation CALayer layout code between my iPhone application and a Mac client (the iPhone inverts the normal Quartz coordinate system for CALayers to match that of the UIViews). All you need to do to enable this is to place the line

self.layer.sublayerTransform = CATransform3DMakeScale(1.0f, -1.0f, 1.0f);

in your initialization code for your layer-hosting UIView. Remember that this will flip your CALayers, so any UIKit text rendering in those layers may also need to be flipped using code similar to the following:

CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0f, self.frame.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);

UIFont *theFont = [UIFont fontWithName:@"Helvetica" size:fontSize];
[text drawAtPoint:CGPointZero withFont:theFont];

CGContextRestoreGState(context);

You can do a similar sort of inversion using a CGAffineTransform, but you will also need to apply a translation to make that work:

CGAffineTransform flipTransform = CGAffineTransformMakeTranslation(0.0f, self.frame.size.height);
flipTransform = CGAffineTransformScale(flipTransform, 1.0f, -1.0f);

You may be able to use the affine transform to convert your origin coordinates using CGPointApplyAffineTransform().

Brad Larson