Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About CGAffineTransformMakeRotation rotation direction?

I'm trying to use CGAffineTransformMakeRotation, and I refer Apple document which says

The angle, in radians, by which this matrix rotates the coordinate system axes. In iOS, a positive value specifies counterclockwise rotation and a negative value specifies clockwise rotation. In OS X, a positive value specifies clockwise rotation and a negative value specifies counterclockwise rotation.

So, I pass parameter 90 degree, it should counterclockwise rotation.
self.myView is gray background color view, and red square view is just for see rotation direction

#define DEGREES_TO_RADIANS(x) (x * M_PI/180.0)
CGAffineTransform rotation = CGAffineTransformMakeRotation( DEGREES_TO_RADIANS(90) );
[self.myView setTransform:rotation];

Before RotationAfter Rotation

But why it clockwise rotation?
I'm trying use in simulator and device both have the same result, clockwise rotation
And then tring to use animation:

#define DEGREES_TO_RADIANS(x) (x * M_PI/180.0)
CGAffineTransform rotation = CGAffineTransformMakeRotation( DEGREES_TO_RADIANS(90) );
[UIView animateWithDuration:0.5
                 animations:^{
                     self.myView.transform = rotation;
                 }
                 completion:^(BOOL finished) {
                     NSLog(@"%@", NSStringFromCGAffineTransform(self.myView.transform));
                 }];

It has the same result, clockwise rotation.

Can somebody explain why, Thanks for the reply.

like image 954
tom19830924 Avatar asked Sep 11 '13 02:09

tom19830924


People also ask

What is CGAffineTransform?

The CGAffineTransform type provides functions for creating, concatenating, and applying affine transformations. Affine transforms are represented by a 3 by 3 matrix: Because the third column is always (0,0,1) , the CGAffineTransform data structure contains values for only the first two columns.

How do you describe rotation direction?

The direction of a rotation in a plane that can be defined in terms of the angle of rotation. If the angle of rotation is positive, the direction of rotation is counterclockwise. If the angle of rotation is negative, then the direction of rotation is clockwise.

How do you rotate a view in Swift?

rorateview.swiftlet bitmap: CGContext = UIGraphicsGetCurrentContext()! //Move the origin to the middle of the image so we will rotate and scale around the center. let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!


3 Answers

This is an error in documentation.

Here they describe matrix and provide equations which they use to do the transform:

enter image description here

If you do the math, you'll see that for positive angles, it gives rotation counterclockwise when Y axis direction is upwards as in OS X and clockwise when Y axis directed downwards as in iOS

For example you may try to transform point (5,0) with 90 degrees, you will get (0,5), which means clockwise for iOS and counterclockwise for OS X.

The same piece of documentation still have the (false) part you quoted:

In iOS, a positive value specifies counterclockwise rotation and a negative value specifies clockwise rotation. In OS X, a positive value specifies clockwise rotation and a negative value specifies counterclockwise rotation.

Which is clearly wrong, because the equations (which are the part of the same document and are pretty standard rotation equations) say the opposite.

like image 96
Serhii Yakovenko Avatar answered Sep 20 '22 13:09

Serhii Yakovenko


This is actually correct behavior, and the documentation describes it correctly.

You're dealing with two different coordinate systems here. Core Graphics' coordinate system has (0, 0) on the bottom left, but UIKit's coordinate system has (0, 0) on the top left. Both coordinate systems have an X-axis with 0 on the left. In other words, UIKit's coordinate system is the Core Graphics coordinate system flipped vertically. The following image demonstrates the difference:

Comparison of UIKit and Core Graphics coordinate systems


Now, let's look at your quote:

The angle, in radians, by which this matrix rotates the coordinate system axes. In iOS, a positive value specifies counterclockwise rotation and a negative value specifies clockwise rotation.

At first glance that seems wrong, but you've missed something. This is a quote from the CGAffineTransformMakeRotation reference. This is part of the Core Graphics reference, not the UIKit reference. It's referring to the rotation as counterclockwise in Core Graphics' coordinate system.

You can picture this rotation in your head by flipping what you're seeing on screen vertically and imagining what the rotation would look like.

In fact, the CGAffineTransformMakeRotation reference has a discussion item which goes on to document this:

The actual direction of rotation is dependent on the coordinate system orientation of the target platform, which is different in iOS and macOS.


The discussion item on CGContext's rotate(by:) method reference describes this behavior a little better:

The direction that the context is rotated may appear to be altered by the state of the current transformation matrix prior to executing this function. For example, on iOS, a UIView applies a transformation to the graphics context that inverts the Y-axis (by multiplying it by -1). Rotating the user coordinate system on coordinate system that was previously flipped results in a rotation in the opposite direction (that is, positive values appear to rotate the coordinate system in the clockwise direction).

like image 39
Ben Kane Avatar answered Sep 20 '22 13:09

Ben Kane


To get anti-clockwise rotation.. make ur angle in -ve eg:

*

imageToBeRotated.transform = CGAffineTransformMakeRotation(-angle); // for anti-clockwise rotation
imageToBeRotated.transform = CGAffineTransformMakeRotation(angle); // for clockwise rotation

*

like image 24
Maniac One Avatar answered Sep 18 '22 13:09

Maniac One