7
votes

OK firstly apologies as I know this kind of question has been asked before more than once. However even after looking at the other questions and answers I have been unable to get this to work for my situation. See below for an example: Fig. 1

All I am simply trying to is work out the angle between P1 and P2 assuming that 0 degrees is as shown above so that I can point an arrow between the 2 in the correct direction. So I do something like this...

Point p1 = new Point(200,300); Point p2 = new Point(300,200);
double difX = p2.x - p1.x; double difY = p2.y - p1.y;
double rotAng = Math.toDegrees(Math.atan2(difY,difX));

Which comes out as: -45, where it should be 45? However it is not simply a case I don't think of it returning a negative result, as for example if I changed P1 to 300,300 (below P2) then the angle should be 0, but is returned as -90.

So I am just wondering if anyone can point out what I am doing wrong to calculate this, or is it even possible to do it this way?

3
You should put this into a function and compute and compare with your expectations the angles for points O and P2 that are closer together. The principal idea to employ atan2 is good. - Lutz Lehmann
Hmm 0 isn't meant to be a point, just what I would expect 0 degrees to point at from P1. Experimenting with a method/function for this now though with setting P1 as 0,0 but not sure that's what u meant :o - Jocelyn Wilde
No, I was referring to the location around the 0 or O mark. - Lutz Lehmann
Ooh sorry, yeh that makes more sense. so the 0,0 position/mark I guess would be 200,200 in this case. - Jocelyn Wilde

3 Answers

5
votes

atan2(Y,X) computes in the standard Cartesian coordinate system with anti-clockwise positive orientation the angle of the point (X,Y) against the ray through (1,0). Which means that X is the coordinate along the zero-angle ray, in your situation X=-difY, and Y is the coordinate in the direction of (small) positive angles, which gives, with your preference for the depicted angle to be 45°, Y=difX. Thus

double rotAng = Math.toDegrees(Math.atan2(difX,-difY));
3
votes

You are confusing with the coordinates system used in geometry vs. one used on computer screen. In geometry you are regular that 0,0 is a point in the left bottom corner. However 0,0 on screen is left - upper corner.

Now, rotate your picture according coordinates of screen and see that the angle is calculated correctly.

So, in general case you can choose one of the following solutions: 1. recalculate corrdinates of your points to screen coordinats and back. 2. if your problem is in angles only you can add π/2 (90 degrees) to your result.

1
votes

With your line double difX = p2.x - p1.x; double difY = p2.y - p1.y;, you are calculating your angle from p2 to 0, so -45 is a correct answer. Try to reverse p1 with p2.

Also, if P1 is changed to 300,300, then you have an angle from 0 ( 0 to P1 and P1 to P2). The angle is indeed 90 or -90 depending if you are seeing from P2 to 0 or 0 to P2.