1
votes

I coded this code here:

     double cosine = (v1.x*v2.x+v1.y*v2.y)/(150*150);               
     double radian = Math.acos(cosine);
     double angle = Math.toDegrees(radian);

V1 and V2 are two vectors, which are simple Point(s)() to keep it simple. Now I calc. the angle between them and it works well. But over 180 deg. , it turns back to 179,178... But I want to have 360°.

The Problem is that for example radian won't get negative, so that I'm able to put it in an if-Segment...

Thanks for advice.

2
This seems more of a math problem than a coding problem. How would you do this with paper and pencil? - azurefrog
yes, i think it's a math problem, too. The way I coded it is the way I would do it on paper(I learned it that way). It seems that the beginning line just give me the smaller angle. - Billabong
acos always return a value for the first two quadrants. You will have to decide the quadrant you are in from your vertices and then adapt your result accordingly. - Dawnkeeper

2 Answers

2
votes

You're using the dot product of the two vectors to calculate the angle between them, but, since the dot product is commutative a.b = b.a - therefore, there is no way to get the sense of the angle, only its magnitude (as you've found out) - acos is ambiguous over 180º.

Try instead using atan2. It should be something like :

double theta1 = Math.atan2(v1.y, v1.x);
double theta2 = Math.atan2(v2.y, v2.x);
double theta = theta1 - theta2;

Note that atan2 always returns an answer in -pi ... pi, so you will have to add pi to make it in the range 0 ... 2.0 * pi.

1
votes

You can get full-range angle (-Pi..Pi for the most of math libraries) using both scalar product and cross product:

radian = Math.atan2(v1.x*v2.y-v1.y*v2.x, v1.x*v2.x+v1.y*v2.y)