Iphone : OpenGL glLookAt : Getting the rotation angle - iphone

I am using glLookAt to control my camera view.
I use the following code to rotate around.
SPEED_TURN is a Const of 0.16 (speed we turn at)
GLfloat v[] = {[self centerAtIndex:0] - [self eyeAtIndex:0],
[self centerAtIndex:1] - [self eyeAtIndex:1],
[self centerAtIndex:2] - [self eyeAtIndex:2]};
[self setCenter:[self eyeAtIndex:0] + cos(SPEED_TURN / 2)*v[0] - sin(SPEED_TURN / 2)*v[2] atIndex:0];
[self setCenter:[self eyeAtIndex:2] + sin(SPEED_TURN / 2)*v[0] + cos(SPEED_TURN / 2)*v[2] atIndex:2];
My question is, how to I get the angle of the camera in degrees?
I tried this
rotAngleDegs = (cos(-SPEED_TURN)*v[0] - sin(-SPEED_TURN)*v[2]) * 180 / PI
However that give numbers from -620 to +620

I don't think you are trying the right functions to give you the angle. The functions "cos()" and "sin()" both take your angle and map it to [-1,1]. If SPEED_TURN is the angle in radians, then you would just use:
float angleInDegrees = (SPEED_TURN * 180) / M_PI;

Take the degress you want and multiply them by pi divided på 180. Then you get the radians to enter:
Radians = Degrees * (pi / 180)
To get the degrees from radians:
Degrees = Radians * (180 / pi)

Related

Rotate UIView without deformation

I'm rotating a UIView based on the accelerometer data, and it works fine except that the UIView is deformed. I'm not sure how to fix the issue. Here's the code in my didAccelerate method:
float kFilteringFactor = 0.175;
CGFloat x = acceleration.x * kFilteringFactor + acceleration.x * (1.0 - kFilteringFactor);
CGFloat y = acceleration.y * kFilteringFactor + acceleration.y * (1.0 - kFilteringFactor);
float radians = M_PI - atan2(y, x);
[_horizonView setTransform:CGAffineTransformMakeRotation(radians)];
Am I performing the rotation incorrectly? I've changed the origin point in Xcode, but that appears to have no effect.
what kind of deformation occures? I think the the rotation is fine.

Figure out angle with right triangle in objective-c

I'm trying to calculate the angle of the click i am making in relationship to the middle of the screen. But maybe i am confused on how atanf is suppsoed to work.
CGPoint pt = [self convertTouchToNodeSpace:[touches anyObject]];
float adj = pt.x - 512;
float opposite = pt.y - 384;
float combined = opposite / adj;
float tan = atanf(combined);
but when i try to NSLog Tan, i just get some giant number like 0.1253649
thoughts?
The right way to convert vector to angle is through atan2 function:
float angle = atan2f (pt.y - 384, pt.x - 512) * 180 / PI;
PS: Are you using cocos2d engine? It has ccpToAngle(...) function.

CGAffineTranformRotate atan2 inaccuration

I'm making transition of my view and always happens something weird, I mean I calculate angle using this code: angle = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x);
And the view rotates but not properly. I mean it rotates in proper direction but the angle is always inaccurate about +/- 0.05 radians. And when I tap again, view rotates into proper position. Any adivices? It's important to me to get angle accurate to 5 places after comma.
Some NSLog to show you the problem:
First rotation first tap and second tap
2012-01-07 01:01:26.283 Wheel[9080:707] Angle: 0.598412
2012-01-07 01:01:29.281 Wheel[9080:707] Angle: -0.070008
Second rotation first tap and second tap
2012-01-07 01:01:31.103 Wheel[9080:707] Angle: -0.679809
2012-01-07 01:01:32.450 Wheel[9080:707] Angle: 0.092595
Third rotation first tap and second tap
2012-01-07 01:01:35.745 Wheel[9080:707] Angle: 0.607844
2012-01-07 01:01:36.945 Wheel[9080:707] Angle: -0.064927
Fourth rotation first tap and second tap
2012-01-07 01:01:41.073 Wheel[9080:707] Angle: -0.635756
2012-01-07 01:01:41.920 Wheel[9080:707] Angle: 0.052361
And I forget to tell you, condition, the difference between points is farther the inaccuration is bigger.
EDIT:
Circle *view = (Circle *) [self view];
for (CircleThumb *thumb in view.subviews) {
CGPoint point = [thumb convertPoint:thumb.centerPoint toView:nil];
CircleThumb *shadow = [[view.overlayView subviews] lastObject];
CGPoint centralPoint = [shadow convertPoint:shadow.centerPoint toView:nil];
CGRect shadowRect = [shadow.superview convertRect:shadow.frame toView:nil];
if (CGRectContainsPoint(shadowRect, point) == YES) {
CGPoint pointInShadowRect = [thumb convertPoint:thumb.centerPoint toView:shadow];
if (CGPathContainsPoint(shadow.arc.CGPath, NULL, pointInShadowRect, NULL)) {
CGAffineTransform current = view.transform;
CGPoint center = view.window.center;
CGPoint currentTouchPoint =centralPoint;
CGPoint previousTouchPoint = point;
long double angle = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x);
[UIView animateWithDuration:0.3f animations:^{
[view setTransform:CGAffineTransformRotate(current, angle)];
}];
[view.delegate circle:view didMoveToSegment:thumb.tag thumb:thumb];
NSLog(#"Angle: %Lf ", angle);
break;
}
}
}
This is code which is part of '- touchesEnded: withEvent:' implementation
I'm making control similar to the one in Convert bot. the "wheels" from my app and from convertbot look similar but mine uses custom drawing.
So Circle is a UIView which we rotate. Circle has got subviews - CircleThumbs. thumb represents single segment of the circle. Points are calculated properly but I won't explain why, because there's no need.
An atan calculation is never entirely correct. And you let iOS calculate cos and sin out of the angle again (cgaffinetransformRotate does that). So you're stacking up trigonometric inaccuracies. And since you calculate only the difference wi the previous angle, I imagine that you are also stacking up inaccuracies over the multiple touch events.
If it is to rotate something, then there is no reason to use trigonometry or angles. You can implement this completely using linear algebra. Something like this:
v.x = touch.x - center.x; v.y = touch.y - center.y;
float length = sqrt(v.x*v.x + v.y* v.y);
if (length < 5 ) break;
v.x /= length; v.y /= length;
// the rotation matrix is
// v.x -v.y
// v.y v.x
rot.x = previous.x * v.x + previous.y * v.y;
rot.y = previous.x * v.y - previous.y * v.x;
CGAffineTransform rotate = CGAffineTransformMake( rot.x, rot.y, -rot.y, rot.x, 0,0);
...
[view SetTransform:CGAffineTransformConcat ( current, rotate )];
...
previous.x = v.x;
previous.y = v.y;
This pseudo code calculates a normalized vector for current point (the one for the previous point was also stored). Then we define a matrix that rotates the previous vector into the new vector. That matrix is concatenated with the existing transformation.
It would be better if the rotation wasn't always calculated from the previous state, but rather from an initial state. The trick is to calculate 'previous' only for the touchdown.

how to get objects degrees?

float mcount=0;
mcount += 0.3;
CGAffineTransform transform = CGAffineTransformMakeRotation(mcount);
Clock.transform = transform;
i want GET Degree!
how to get rotation(degree) of this Object ? for exampke 90 degree.
i have Action Script 3 example :
myInt = clock_mc.rotation;
i need this method on Cocoa Touch
If I'm understanding your question correctly then a bit of mathematics can help here:
angleInRadians = angleInDegrees * M_PI / 180.0
To get the reverse, you reverse your equation. So first moving the division by 180 on the right to the left results in multiplying by 180.0
angleInRadians * 180.0 = angleInDegrees * M_PI
Now move the multiply by M_PI (the value of PI which is something like 3.1415962...) to the left, you reverse the operation:
(angleInRadians * 180.0) / M_PI = angleInDegrees
Now to make it nice for the program to use, we write it like so:
angleInDegrees = (angleInRadians * 180.0) / M_PI
So in your program, you could write your code like this:
var angleInDegrees = 0;
...
angleInDegrees = mcount * 180.0 / M_PI;
If you want to use a function then:
-(float) getAngleInDegrees:(float) radians
{
float angleInDegrees = 0;
angleInDegrees = radians * 180.0 / M_PI;
return angleInDegrees;
}
I think you want how to convert degrees into radians:-
for this you can use this formula:-
static inline double radians (double degrees) { return degrees * M_PI/180; }
UPDATED!
Do you want to get result rotation angle of Clock object?! If so, use this:
double rotationInRadians = atan2(Clock.transform.b, Clock.transform.a);
int rotationInDegrees = (int)round(rotationInRadians * 180 / M_PI);
Read this for details & explanation.

Cocos2d iPhone: Rotate Sprite using Accelerometer

I'm trying to rotate a sprite using the accelerometer. when I tilt right, I want him to rotate slightly to the right, and when I tilt left, I want him to rotate slightly to the left...
Thanks in advance,
Reed
Firs off - in your h file you need to make the following variables:
UIAccelerationValue accelerationX;
UIAccelerationValue accelerationY;
float currentRawReading;
float calibrationOffset;
Also ensure that your h file has:
#interface myViewName : UIViewController <UIAccelerometerDelegate>
Then in your .m file just below your imports at the top put:
#define kFilteringFactor 0.05
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};
Then in your .m file on your viewDidLoad Function put:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
also add the following function to your .m file:
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
accelerationX = acceleration.x * kFilteringFactor + accelerationX * (1.0 - kFilteringFactor);
accelerationY = acceleration.y * kFilteringFactor + accelerationY * (1.0 - kFilteringFactor);
// keep the raw reading, to use during calibrations
currentRawReading = atan2(accelerationY, accelerationX);
float rotation = -RadiansToDegrees(currentRawReading);
targetView.transform = CGAffineTransformMakeRotation(-(DegreesToRadians(rotation)));
//targetView.transform = CGAffineTransformRotate(targetView.transform, -(rotation * 3)); //if you want easing
}
you will have to tweak it slightly based on what view or object you are targeting -- but thats pretty much it.
Hope this helps,
Michael
Shouldn't be too difficult. Just have somewhere in your code that handles the UIAccelerometerDelegate class and apply changes to your sprites based on the values you receive through parameters to the – accelerometer:didAccelerate: callback.
Apple docs for the delegate class are available at...
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIAccelerometerDelegate_Protocol/UIAccelerometerDelegate/UIAccelerometerDelegate.html
In the delegate function of accelerometer just write the code -->>
float angleRadians = atanf((float)X_Position / (float)Y_Position);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = 1 * angleDegrees;
sprite.rotation = cocosAngle;
and the sprite will get rotated to desired angle with changes in the values of X_position, Y_Position and angle.
Njoy.. :)