iOS Swift Detecting Image Rotation - ios

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!

Related

Get the actual angle after the superview is rotated

I have 5 subviews(White) added to the superview(Gray), when I rotate the superview I want to know the angle(like 1 and 2) of each of the subview with the red circle.(the center of the subviews and the red circle are ON the same circle)
Start Position:
Rotated Position:
From your comment you appear to want to determine the coordinates of the centres of your five circles for a given rotation. The centres will all lie on a circle. So your question boils down to what are the coordinates of a point on a circle of radius r for an angle θ. The parametric equations for a circle give you that:
x = r cos θ
y = r sin θ
The angle, θ, in these equations is measured in radians from the positive x-axis in an anti-clockwise direction. If your angle are in degrees you will find the M_PI constant for π useful as:
360 degrees = 2 π radians
The rest is simple math, take your angle of rotation to give you the angle for A (remembering to adjust for 0 being the x-axis and measuring anti-clockwise if needed), the other centres are multiples of 72 degrees (0.4 π radians) from this.
HTH
I'm not sure I completely understand your question, but if you just need to take a known point and rotate it a certain number of degrees, check out the docs for CGAffineTransform.
For example:
CGAffineTransform rotation = CGAffineTransformMakeRotation (angle);
CGPoint rotatedPoint = CGPointApplyAffineTransform (startingPoint, rotation);
This rotation matrix is around (0, 0) and the angle is in radians, so you will need to subtract the center of your superview's bounds to get an offset relative to the center, do the rotation, and add back in the center. Or you can build an affine transform made up of that translation, rotation, and inverse translation, and then apply that to your starting point as above.
Given that you already seem to know the main rotation angle, this will give you the angles in the range -180 .. +180 and positions of each of the white discs:
GCFloat toRads = M_PI / 180.0;
CGFloat angleA = self.rotationInDegrees;
if (angleA > 180) angleA -= 360;
CGFloat xA = self.radius * sinf(angleA * toRads);
CGFloat yA = self.radius * cosf(angleA * toRads);
CGFloat angleB = angleA + 72;
if (angleB > 180) angleB -= 360;
CGFloat xB = self.radius * sinf(angleB * toRads);
CGFloat yB = self.radius * cosf(angleB * toRads);
etc...
(This assumes your zero degrees is from the vertical. If it's from the horizontal swap cos and sin over).

iOS - Rotate 3D object in scenekit

Hi I'm trying to rotate a 3D object in scenekit with no success heres my code:
let rotateAction = SCNAction.rotateByAngle(90, aroundAxis: SCNVector3Make(0, 1, 0), duration: 3)
let moveAction = SCNAction.moveByX(25, y: 0, z: 0, duration: 6)
ship.runAction(rotateAction, completionHandler: {ship.runAction(moveAction)})
I have managed to get it rotating on the correct axis but for some reason its not rotating by the 90 degrees that I've stated it just spins numerous times for the 3 seconds. I appreciate any help thanks.
the angle for rotateByAngle is in radians, so for 90 degrees you'd have to make the angle 1.571 radians.
if you'd like to be more thorough, add a little function to convert degrees to radians. it also will make the code easier to understand in the future.
func degToRadians(degrees:Double) -> Double
{
return degrees * (M_PI / 180);
}
SCNAction Class Reference

How to apply force at an speicific angle in spriteKit?

I want to give Force to my SKSpriteNode at specific angle.
So, How to treat my CGVector for give force at specific angle?
I had searched for it but unfortunately not getting any good way.
What i wants to achieve :
My SKSpriteNode moving towards the screen. There are buttons on top like 30,45,60.
So if user press button(i.e. that Button contain "30") then i had to move my SKSpriteNode to 30 degree with same speed.
Please help me towards it if any of you can help me regarding this.
First, you will need to convert the angle in degrees to radians by multiplying it by pi / 180
CGFloat angleInRadians = angleInDegrees * M_PI / 180;
You can then determine the vector components in that direction by
CGFloat dx = cosf(angleInRadians);
CGFloat dy = sinf(angleInRadians);
and finally apply a force to the sprite with
[sprite.physicsBody applyForce:CGVectorMake(dx*scale, dy*scale)];
where scale determines how much force is applied.
Optionally, you can rotate the sprite to face in the same direction as its motion by
sprite.zRotation = angleInRadians + offset;
where offset is the difference in angle, in radians, between your sprite's image and zero degrees. For example, if your sprite is facing up when zRotation is zero, offset should be -M_PI_2.

SKSpriteNode zrotation M_PI is infuriating

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

How to draw line given a center point and angle in iOS?

This is so much an iOS question as it is my current inability to do coordinate geometry. Given a CGPoint to act as a point that the line will pass through and an angle in radians. How do I draw a line that extends across to the bounds of the screen (infinite line)?
I am using Quartz2d to do this and the API for creating a line is limited to two points as input. So how do I convert a point and angle to two points on the bounds of the iOS device?
This begins with simple trigonometry. You need to calculate the x and y coordinate of the 2nd point. With an origin of 0,0 and treating a line that goes straight to the right as 0 degrees, and going counterclockwise (anti-clockwise for some of you), you do:
double angle = ... // angle in radians
double newX = cos(angle);
double newY = sin(angle);
This assumes a radius of 1. Multiply each times a desired radius. Pick a number that will be bigger than the screen such as 480 for an iPhone or 1024 for an iPad (assuming you want points and not pixels).
Then add the original point to get the final point.
Assuming you have CGPoint start, double angle, and a length, your final point is:
double endX = cos(angle) * length + start.x;
double endY = sin(angle) * length + start.y;
CGPoint end = CGPointMake(endX, endY);
It's OK if the end point is off the screen.

Resources