help to calculate atan2 properly
Asked Answered
P

4

9

I need to calculate the angle between lines. I need to calculate atan. So I am using such code

static inline CGFloat angleBetweenLinesInRadians2(CGPoint line1Start, CGPoint line1End) 
{
    CGFloat dx = 0, dy = 0;

    dx = line1End.x - line1Start.x;
    dy = line1End.y - line1Start.y;
    NSLog(@"\ndx = %f\ndy = %f", dx, dy);

    CGFloat rads = fabs(atan2(dy, dx));

    return rads;
}

But I can't get over 180 degrees(( After 179 deg going 178..160..150 and so on.

I need to rotate on 360 degrees. How can I do it? What's wrong?

maby this helps:

//Tells the receiver when one or more fingers associated with an event move within a view or window.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSArray *Touches = [touches allObjects];
    UITouch *first = [Touches objectAtIndex:0];

    CGPoint b = [first previousLocationInView:[self imgView]]; //prewious position
    CGPoint c = [first locationInView:[self imgView]];          //current position

    CGFloat rad1 = angleBetweenLinesInRadians2(center, b);  //first angel
    CGFloat rad2 = angleBetweenLinesInRadians2(center, c);  //second angel

    CGFloat radAngle = fabs(rad2 - rad1);           //angel between two lines
    if (tempCount <= gradus)
    {
        [imgView setTransform: CGAffineTransformRotate([imgView transform], radAngle)];
        tempCount += radAngle;
    }

}
Penoyer answered 2/11, 2010 at 16:54 Comment(0)
T
7

Remove the fabs call and simply make it:

CGFloat rads = atan2(dy, dx);
Thinner answered 2/11, 2010 at 16:59 Comment(3)
@yozhik: Maybe you should explain what doesn't work. What is the expected result and what are you seeing?Thinner
I have a decart coordinate system. On which I'm proecting picture. There is imaging zero. When I take and move my picture in upper 180 degrees - all allrigth. When I'm trying to move ander 180 degrees, for example 190 - it shows me 170 degrees. I need that there where 190 degrees. You see...Penoyer
@yozhik: Try removing the other fabs in fabs(rad2 - rad1) also.Thinner
I
9

atan2 returns results in [-180,180] (or -pi, pi in radians). To get results from 0,360 use:

float radians = atan2(dy, dx);
if (radians < 0) {
    radians += M_PI*2.0f;
}

It should be noted that it is typical to express rotations in [-pi,pi] and thusly you can just use the result of atan2 without worrying about the sign.

Incorporeal answered 2/11, 2010 at 16:58 Comment(2)
What didn't work? I assume you substituted a proper constant for TWO_PI as well.Incorporeal
There's no reason I can see that it wouldn't work to get your angle correct. What values specifically are being generated incorrectly?Incorporeal
T
7

Remove the fabs call and simply make it:

CGFloat rads = atan2(dy, dx);
Thinner answered 2/11, 2010 at 16:59 Comment(3)
@yozhik: Maybe you should explain what doesn't work. What is the expected result and what are you seeing?Thinner
I have a decart coordinate system. On which I'm proecting picture. There is imaging zero. When I take and move my picture in upper 180 degrees - all allrigth. When I'm trying to move ander 180 degrees, for example 190 - it shows me 170 degrees. I need that there where 190 degrees. You see...Penoyer
@yozhik: Try removing the other fabs in fabs(rad2 - rad1) also.Thinner
C
1

Your problem is that the result of atan2 is between -180 and +180 degrees. If you want it to be between 0 and 360 then move the result to sure be a positive value, and then do a modulo. For example:

let angle = fmod(atan2(dx,dy) + .pi * 2, .pi * 2)
Chainplate answered 19/5, 2020 at 0:44 Comment(0)
W
0

Use this function in Swift. This makes sure the angle from "fromPoint" to "toPoint" lands between 0 to <360 (not including 360). Please note, the following function assumes that CGPointZero is at top left corner.

func getAngle(fromPoint: CGPoint, toPoint: CGPoint) -> CGFloat {
    let dx: CGFloat = fromPoint.x - toPoint.x
    let dy: CGFloat = fromPoint.y - toPoint.y
    let twoPi: CGFloat = 2 * CGFloat(M_PI)
    let radians: CGFloat = (atan2(dy, -dx) + twoPi) % twoPi
    return radians * 360 / twoPi
}

For the case where the origin is at the bottom left corner

let twoPi = 2 * Float(M_PI)
let radians = (atan2(-dy, -dx) + twoPi) % twoPi
let angle = radians * 360 / twoPi
Warchaw answered 15/2, 2015 at 1:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.