What do I have to do, if I need to rotate a UIImageView? I have a UIImage which I want to rotate by 20 degrees.
The Apple docs talk about a transformation matrix, but that sounds difficult. Are there any helpful methods or functions to achieve that?
If you want to turn right, the value must be greater than 0 if you want to rotate to the left indicates the value with the sign "-". For example -20.
CGFloat degrees = 20.0f; //the value in degrees
CGFloat radians = degrees * M_PI/180;
imageView.transform = CGAffineTransformMakeRotation(radians);
Swift 4:
let degrees: CGFloat = 20.0 //the value in degrees
let radians: CGFloat = degrees * (.pi / 180)
imageView.transform = CGAffineTransform(rotationAngle: radians)
A transformation matrix is not incredibly difficult. It's quite simple, if you use the supplied functions:
imgView.transform = CGAffineTransformMakeRotation(.34906585);
(.34906585 is 20 degrees in radians)
Swift 5:
imgView.transform = CGAffineTransform(rotationAngle: .34906585)
Swift version:
let degrees:CGFloat = 20
myImageView.transform = CGAffineTransformMakeRotation(degrees * CGFloat(M_PI/180) )
Swift 4.0
imageView.transform = CGAffineTransform(rotationAngle: CGFloat(20.0 * Double.pi / 180))
Here's an extension for Swift 3.
extension UIImageView {
func rotate(degrees:CGFloat){
self.transform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI/180))
}
}
Usage:
myImageView.rotate(degrees: 20)
_YourImageView.transform = CGAffineTransformMakeRotation(1.57);
where 1.57 is the radian value for 90 degree
This is an easier formatting example (for 20 degrees):
CGAffineTransform(rotationAngle: ((20.0 * CGFloat(M_PI)) / 180.0))
As far as I know, using the matrix in UIAffineTransform is the only way to achieve a rotation without the help of a third-party framework.
Related
I am planning to create an image rotation UI like apple
Need an idea how can I implement this or if anyone can help me with any open source or apple API for this.
you can use this:
//rotate 45 degrees
imgView.transform = CGAffineTransform(rotationAngle: (.pi / 4))
//rotate 90 degrees
imgView.transform = CGAffineTransform(rotationAngle: (.pi / 2))
and so on as per your requirement, calculate and transform image on every event...
I have an app which animates a needle on a meter as long as the user is pressing on the screen. When the finger is lifted I need to know the rotation angle of the needle. I remove all animations as soon as the finger is lifted but I can't figure how to get the current rotation angle of the needle.
It is quite simple, this is the full solution:
Sample Setup:
imageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 6) // just to test (it is 30 in degrees and 0.523598775598299 in radians)
Code:
let rad: Double = atan2( Double(imageView.transform.b), Double(imageView.transform.a))
let deg: CGFloat = CGFloat(rad) * (CGFloat(180) / CGFloat.pi )
print(deg) // works, printing 30
where deg = degrees and rad = radians
Explanation:
The first line is getting the radians, and the second line is multiplying the radians by the equivalent of a radian in degrees, to get the degrees.
NOTES:
In CGAffineTransform(rotationAngle: someValue), someValue is, in fact, the radians of the angle, it is not measured in degrees. More information about:
radian
degree
PI
The value in degrees of the radian CGFloat.pi is 180, therefore you can test it for any angle depending on this.
Let me know if this helps!
In my app I'm using UIBezierPath to draw an arc into a circle. I'm trying to correlate a number to radians. So let's say a user has a certain number of points, and the points are capped at 100 points. I want 100 points to be 360 degrees. I want the first 33% of the circle to be green, and then from 34% to the next 66% of the circle to be stroked in orange, and then from 67% to 100% in red.
The issue I'm having here is converting percents of a circle to radians. When creating a UIBezier path, I need to provide a startAngle and endAngle, and I'm having a bit of trouble converting these points to radian values.
How would I go about solving this?
Thanks
CGFloat radians = percent * 0.01 * 2 * M_PI;
Simple algebra.
Swift version
Making it more general purpose, you can write a conversion function:
func radiansFromPercent(_ percent: CGFloat) -> CGFloat {
return percent * 0.01 * 2 * CGFloat.pi
}
I think what you want is the unit circle. Remember back to trigonometry when you used the unit circle? Same thing will apply here. If you need to get π - in Swift just say let π = CGFloat.pi (hold alt+p for the special character). In Objective-C - I think it's CGFloat π = M_PI;.
You could go from zero to 2π/3 for the first 1/3, then from 2π/3 to 4π/3, then from 4π/3 to 2π (full circle).
I should not that I didn't make this graphic - it's from a tutorial on RayWenderlich.com - but it's oriented perfectly for the iOS coordinate system.
Objective-C
CGFloat fullCircle = 2 * M_PI ; // M_PI Pi number which is half of the circle in radian
CGFloat startPoint = 0.0 ;
CGFloat endPoint = fullCircle * 0.33 ;
// Assuming circling clockwise
// .... Draw first step UIBezierPath
startPoint = endPoint ;
endPoint = startPoint + fullCircle * 0.33 ;
// .... Draw second step UIBezierPath
startPoint = endPoint ;
endPoint = fullCircle - startPoint ; // This to make sure the whole circle will be covered
// .... Draw the last step UIBezierPath
Swift
let fullCircle = 2 * M_PI // M_PI Pi number which is half of the circle in radian
var startPoint: Float = 0.0
var endPoint: Float = fullCircle * 0.33
// Assuming circling clockwise
// .... Draw first step UIBezierPath
startPoint = endPoint
endPoint = startPoint + fullCircle * 0.33
// .... Draw second step UIBezierPath
startPoint = endPoint
endPoint = fullCircle - startPoint // This to make sure the whole circle will be covered
// .... Draw the last step UIBezierPath
so all i want to do is rotate an SKSPriteNode by 90 degrees. just that. It should be simple yet my first approach, assuming it would be degrees, turns the object in completely the wrong diection. so i head to google > stackoverflow. plenty of answers to do with this, okay so ill try using M_PI or some variation. nope. 'Double' is not convertible to 'CGFloat'. google again. "Try using skaction with blah blah" nope.
how difficult can it be to rotate a sprite? or am i insane
This seems to work fine for me. Understanding conversions between radians and degrees is important.
http://en.wikipedia.org/wiki/Radian#Conversion_between_radians_and_degrees
sprite.zRotation = CGFloat(M_PI_2)
I'm assuming you're using Swift based on your "'Double' is not convertible..." comment.
The following rotates a sprite 90 degree counterclockwise:
sprite.runAction(SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 1.0))
The following rotates a sprite 90 degree clockwise:
sprite.runAction(SKAction.rotateByAngle(CGFloat(-M_PI_2), duration: 1.0))
Another option would be to create an extension for Int:
extension Int
{
var deg2Rad : CGFloat
{
return CGFloat(self) * CGFloat(M_PI) / 180.0
}
}
then use it like this:
sprite.runAction(SKAction.rotateByAngle(180.deg2Rad, duration: 1.0))
Makes it more human-readable.
let threesixty:CGFloat = 360 * .pi / 180
I want to get scale factor and rotation angle form view. I've already applied CGAffineTransform to that view.
The current transformation of an UIView is stored in its transform property. This is a CGAffineTransform structure, you can read more about that here: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html
You can get the angle in radians from the transform like this:
CGFloat angle = atan2f(yourView.transform.b, yourView.transform.a);
If you want the angle in degrees you need to convert it like this:
angle = angle * (180 / M_PI);
Get the scale like this:
CGFloat scaleX = view.transform.a;
CGFloat scaleY = view.transform.d;
I had the same problem, found this solution, but it only partially solved my problem.
In fact the proposed solution for extracting the scale from the transform:
(all code in swift)
scaleX = view.transform.a
scaleY = view.transform.d
only works when the rotation is 0.
When the rotation is not 0 the transform.a and transform.d are influenced by the rotation. To get the proper values you can use
scaleX = sqrt(pow(transform.a, 2) + pow(transform.c, 2))
scaleY = sqrt(pow(transform.b, 2) + pow(transform.d, 2))
note that the result is always positive. If you are also interested in the sign of the scaling (the view is flipped), then the sign of the scaling is the sign of transform.a for x flip and transform.d for y flip. One way to inherit the sign.
scaleX = (transform.a/abs(transform.a)) * sqrt(pow(transform.a, 2) + pow(transform.c, 2))
scaleY = (transform.d/abs(transform.d)) * sqrt(pow(transform.b, 2) + pow(transform.d, 2))
In Swift 3:
let rotation = atan2(view.transform.b, view.transform.a)