2

I have been looking for an answer for several hours now, and have turned up nothing. If this is a duplicate, I apologize but I have been unable to find a solution to my specific problem on StackOverflow.

I have a function that finds the angle between a point and the y-axis:

public static double getAngle(float x1,float y1) {
    float y_x = 0;
    float y_y = 1;
    float p_x = x1;
    float p_y = y1;

    float theta = (float)Math.atan2((p_x-y_x),(p_y-y_y));
    return (float)Math.toDegrees(theta)
}

Then when I call it, i get strange behavior:

getAngle(1,1); //returns 90.00000250447816
getAngle(5,5); //returns 51.34019265119512
getAngle(10,10); //returns 48.012787449847956
getAngle(100,100); //returns 45.287917631417216
getAngle(1000,1000); //returns 45.02866072599646

I know the answer is 45. It would appear the function `getAngle(x,x) is converging on 45 as the limit of x approaches infinity. The issue is I need this function to work for values between 0.01 and 10.0

Does anybody know why the function is behaving this way and how I can get the answer I am looking for?

P.S. I initially tried using the dot-product identity acos((ax*bx+ay*by)/|a||b|) and got a similar problem

3
  • It could be because of imprecision. Try using doubles instead of floats and tell us what happens. Commented Jul 28, 2013 at 21:18
  • So you are essentially trying to get the angle between the vector [x1 y1] and the vertical(or y-axis)? If you are your math is wrong, the first should be 90. Commented Jul 28, 2013 at 21:19
  • 1
    Those numbers look right for y_y = 1. Perhaps you meant to set that value to 0? Commented Jul 28, 2013 at 21:21

2 Answers 2

2

You should simply use

float theta = (float) ((Math.PI/2) - Math.atan2(y1, x1));

The reason that your getAngle(x, x) approaches the correct angle when x approaches infinity is that you were effectively computing

Math.atan2(x, x-1)

which is equivalent to

Math.atan(x / (x-1))

and hence obviously approaches the correct

Math.atan(1)

when x approaches infinity.

Sign up to request clarification or add additional context in comments.

1 Comment

This almost worked. I had to use the code provided by Fraserk. However yours explained what was going on very well and also helped me fix my rotation matrices in another part of the function. Thanks mate!
2

It seems like your math is wrong. My approach would be to find the angle to the horizontal and do 90 minus that. For example:

double theta = Math.PI/2 - Math.atan2(y1,x1); //answer in radians

Why you are wrong is because you are subtracting the vectors from each one another so that you are getting the angle of a triangle defined by the new vector. By measuring it to the X axis and subtracting it from 90 it will be a lot easier :D

1 Comment

atan2 returns radians. Needed to convert 90 to (Math.PI/2). Otherwise this worked! Thanks for the help mate. Between the answers you and Heuster provided I fully understood my folly!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.