Why did atan2 give me different values from asin?

2.4k views Asked by At

I was trying to calculate the value of an angle of a right triangle. The sides were the opposite, and the hypotenuse, which happens to be adjacent to the angle as well. One code written in Java used atan2 to get the angle. When I used atan2 in C, I got differing values. The only way for me to get the correct values was to use asin.

Here is the code snippet in C:

for(i = 0; i < n; i++)
{
    m = sqrt( (x - l[i].x) * (x - l[i].x) + (y * y) );

    dist = abs(x - l[i].x);

    ang = asin(dist/m) * 180.0 / 3.14159265;

    if(ang <= (l[i].a + .01))
        total += (double) l[i].I/(m*m);
}

Here is the code snippet in Java:

for (j = 0; j < n; j++)
     {
        d = Math.sqrt( (xs - lights[j]) * (xs - lights[j]) + (ys * ys) );

        w = Math.abs(xs - lights[j]);

        ang = Math.atan2(w, ys) * 180.0 / 3.14159265;

        if (ang <= angles[j] + 0.01)
        {
           total += (double ) intensities[j] / (d * d);
        }
     }

Can anyone shed some light on this issue?

2

There are 2 answers

1
Peter On

opposite/hypotenuse = sine, hence one should use asin to get the angle.

0
chux - Reinstate Monica On

(see below set-up conditions)

OP asks: "using atan2 in Java gives me the same angle as using asin in C. WHY?".
That's simply that the sin(ang) = opposite/hypotenuse = dist/m and tan(ang) = opposite/adjacent = w/ys.

OP asks: "using atan2 in C gives me a different angle than using atan2 in Java. WHY?"
This is a lot trickier because the OP did not post the offending code. OP did not state what some of these differing values were or provide test data. We are left with educated guesses.

The first hunch is OP did not use C atan2() parameters in the correct order. C and Java use atan2() in the same order (y,x). Excel uses the (x,y) order. Given OP is using variables named y for the x parameter, this is reasonable.

2nd idea is OP did not use the same sides in C which should have been atan2(dist, y).

3rd idea there is a sign (not sine) issue. Need test data.


There are other subtle problems with the code, like why use 3.14159265 instead of M_PI? What happens in C if dist/m is just above 1.0 (rounding issues)?


Given a right triangle with
height A = dist = abs(x - l[i].x) or w = abs(xs - lights[j])
width B = y or ys
hypotenuse C = m or d
Angle ang opposite side A

The ang is asin(dist/m)
and ang is atan(w/ys) = atan2(w, ys)