angle between two points

hi, if I have two points Point2D.Double p; Point2D.Double q; how do you find the angle between them (measured from a vertical bar)?thanks,asjf
[191 byte] By [asjfa] at [2007-9-29 9:23:28]
# 1

Point2D.Double p = new Point2D.Double(4.0,3.0),

q=new Point2D.Double(-3.0,4.0);

double angle = Math.atan(p.x/p.y)-Math.atan(q.x/q.y);

System.out.println("angle(radians)="+angle+", (degrees)="+

angle/Math.PI*180);

bbrittaa at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 2
thanks :)
asjfa at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 3

Your better off using atan2() and not atan() since the code above could cause dive by zero exceptions if either point has y=0.

Point2D.Double p = new Point2D.Double(4.0,3.0),

q=new Point2D.Double(-3.0,4.0);

double angle = Math.atan(p.y,p.x)-Math.atan(q.y,q.x);

System.out.println("angle(radians)="+angle+", (degrees)="+ angle/Math.PI*180);

eduar09a at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 4
Ack in my haste I forgoet to change the Math.atan() calls to Math.atan2()
eduar09a at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 5

Just out of curiosity, how on earth did you understand that question? I seem to remember that between any two points exists a LINE, but in order to have an angle you would have to have 3 points (one being the vertex). As I contemplate this question, my first thought is that the answer would depend on the placement of the "vertical line" and from which point on that vertical line you would be measuring the angle between the original two points. I am not challenging your answer, I am merely baffled that an answer could be formulated based on the VERY little information presented.

nochidsa at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 6

It's easy to understand if you think in terms of complex numbers.

Every (x,y) point on the complex plane can be equally well-represented by (r,t), where r = sqrt(x*x + y*y) and t = atan(y/x).

There's an implicit origin at (0,0) in the complex plane. That's the third point that the solution takes advantage of.

The solution simply calculates the angle for each point in the complex plane and subtracts the two to get the angular difference between them.

What I'm describing would be relative to the horizontal x-axis. There must be a transformation in there to give the results relative to the vertical axis, as the OP requested. - MOD

duffymoa at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 7

"measured from a vertical bar ?" I know how to measure an angle AOB where O is the origin, but I'm not sure what measuring from a bar might be.

The dot product of any two unit vectors is the cosine of the angle, so you can use that and avoid that pesky arctan.

theta = Math.acos(

(a.getX() * b.getX() + a.getY() * b.getY())

/ a.distance(0,0) / b.distance(0,0) );

pmuurray@bigpond.coma at 2007-7-14 22:57:49 > top of Java-index,Other Topics,Algorithms...
# 8
Oh! The OP means "measured from an arbitrary position on the X axis"! Well, thats easily done. Just subtract x from both points, and proceed.
pmuurray@bigpond.coma at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 9
Actually, the cosine ISN'T the dot product of two vectors, it's the dot product divided by the product of the magnitudes of the two vectors.When did atan become "pesky"? It's a perfectly legit function. - MOD
duffymoa at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 10
Just read your reply more closely - you did specify unit vectors, both of magnitude one, so your remark about cosine and dot product IS correct. My apologies - I was going too fast.I still defend the honor of atan(), though. ;-) MOD
duffymoa at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 11

Point2D.Double p = new Point2D.Double(4.0,3.0),

q=new Point2D.Double(-3.0,4.0);

double angle = Math.atan(p.y,p.x)-Math.atan(q.y,q.x);

System.out.println("angle(radians)="+angle+", (degrees)="+ angle/Math.PI*180);

Defend the hionour of atan2? Gaaah! you are making two[/d] calls to a math library! My code only needs to make one, to acos().

Firstly, of course, in the atan method the order of the operands is significant. In the dot product method, they are not. One gives "the angular distance from p to q", wheras the other gives "the angle between p and q".

Secondly, atan2 behaves ... oddly sometimes, I can never get straight whether the results are 0 to PI, or -PI/2 to PI/2. So if the angle is 60 degrees, you might get 60, -60, 120, -120, 300, -300 etc depending subtly on what the two points p and q contain, and all in floating point. You get the situation where the result flicks between two wildly different values when you move one of the points by a pixel, and the nature of the flick can change depending on which quarant the points are in. Been there, done that. The dot product method, by contrast, goes smoothly from 0 to PI.

Someone pass me a saucer of milk.

pmuurray@bigpond.coma at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 12
By the way, you want to know something excessively cool? JBuilder9 will allow you to keep your source files encoded in UTF-8. This means that you can use variables in your source that are actual greek letters - pi, delta, theta and so on.Some people are easily amused. I'm one of
pmuurray@bigpond.coma at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 13
Java3D comes with a class javax.vecmath the lets you do lots of vector and point calculations including the angle between two vectors.
UlrikaJa at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 14

Hi pmurray,

Point well taken - one call to acos is better than atan2. That doesn't make it a superior function, that just says it's being used more efficiently by your algorithm. That's all I'm saying.

One more method call won't break a program's back. I'm not saying that I'm a fan of installing bubble sort and hoping for the best, but I'd wait until a profiler told me I had a problem in this case. Don't optimize prematurely. You don't always know where the bottleneck is. (Except maybe in this trivially obvious case.) ;)

I don't have a problem with the order of the arguments - I read the javadocs.

The "wild" nature you cite is due to the fact that atan2 is singular at +/-(pi/2), and it's periodic with period pi. It's not wild - a mathematician would say that's just the nature of the beast. But you're correct again - cosine is a smooth, non-singular function with an infinite number of continuous derivatives.

There's nothing wrong with anything you said. I'm just playing friendly devil's advocate. - MOD

duffymoa at 2007-7-14 22:57:50 > top of Java-index,Other Topics,Algorithms...
# 15

> Point well taken - one call to acos is better than atan2. That doesn't make it a superior function, that just says it's being used more efficiently by your algorithm. That's all I'm saying.

Look, I'm just engaging in a little macho swaggering and petty point-scoring. Don't mind me. :-)

pmuurray@bigpond.coma at 2007-7-19 5:12:30 > top of Java-index,Other Topics,Algorithms...
# 16

I would too, pmurray.

To be frank, I think what I said defending atan2 is pure ****, and I'm shocked that you didn't call me on it. ;)

I've decided that your point about using acos to calculate that angle is far superior. In my Complex class, I've changed the code to calculate the radius in the usual way and then get the angle using acos, per your suggestion. The lack of singularities in acos is impossible to pass up. Thanks - MOD

duffymoa at 2007-7-19 5:12:30 > top of Java-index,Other Topics,Algorithms...
# 17

> The "wild" nature you cite is due to the fact that

> atan2 is singular at +/-(pi/2), and it's periodic with

> period pi. It's not wild - a mathematician would say

> that's just the nature of the beast

tan is singular at +/-((2n+1)pi/2) and has period pi.

Neither atan nor atan2 is periodic. As the range of tan is from -infinity to +infinity, the domain of atan is the same. The 2D domain of atan2 allows atan2 to range over -pi to + pi, giving a result over any of the four quadrants:

public class Atan {

public static void main(String[] args) {

System.out.println(Math.toDegrees(Math.atan2(-1, -1)));

System.out.println(Math.toDegrees(Math.atan2(1, 1)));

System.out.println(Math.toDegrees(Math.atan2(1, 0)));

System.out.println(Math.toDegrees(Math.atan2(-1, 0)));

System.out.println(Math.toDegrees(Math.atan(-1 / -1)));

System.out.println(Math.toDegrees(Math.atan(1 / 1)));

System.out.println(Math.toDegrees(Math.atan(Double.POSITIVE_INFINITY)));

System.out.println(Math.toDegrees(Math.atan(Double.NEGATIVE_INFINITY)));

}

}

Pete_Kirkhama at 2007-7-19 5:12:30 > top of Java-index,Other Topics,Algorithms...
# 18
I stand corrected again, Pete. Thank you for pointing out my error and contributing to my re-education. It's been too long since I did that kind of work. Sincerely, MOD
duffymoa at 2007-7-19 5:12:30 > top of Java-index,Other Topics,Algorithms...