Java-Gaming.org Hi !
 Featured games (83) games approved by the League of Dukes Games in Showcase (577) Games in Android Showcase (157) games submitted by our members Games in WIP (627) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 How do we calculate the angle between two vectors?  (Read 6251 times) 0 Members and 1 Guest are viewing this topic.
zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Posted 2007-03-05 22:02:21 »

It's amazon how so many people fall here.
K.I.L.E.R

Senior Devvie

Java games rock!

 « Reply #1 - Posted 2007-03-06 02:29:01 »

u.v/|u|.|v| = cos(t)

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed.
hano

Senior Newbie

Projects: 1

http://es.geocities.com/luisja80

 « Reply #2 - Posted 2007-03-06 08:47:56 »

Very good Geometry introduction.

http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry1
http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2

Also, you can join TopCoder,

zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #3 - Posted 2007-03-06 14:34:01 »

u.v/|u|.|v| = cos(t)

Wrong for obvious reasons.

'cos(t) = a' has two solutions for t.
jojoh

JGO Knight

Medals: 5
Projects: 7

games4j.com

 « Reply #4 - Posted 2007-03-06 21:19:28 »

Well, if you have one angle ang between the two vectors then you will have another angle = 360 - ang between the two vectors (obviously).     That is unless the vectors are parallel, then the two angles are the same. I find it a bit odd that this should be a problem since the web is packed with solutions and examples for exactly this. I googled and looked at hit ~100 and it described it just fine. By the way KILER has a . too much in the equation

zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #5 - Posted 2007-03-06 21:51:16 »

Well, if you have one angle ang between the two vectors then you will have another angle = 360 - ang between the two vectors (obviously).

That reduces the answer to two complementary angles but we still need to find a way to know which one it is. There is only one angle between two vectors in a Cartesian Coordinate system and there's only one method to find this angle that works for all dimensions. However there's a much faster way for 2D vectors. Do you know what it is?

Quote
I find it a bit odd that this should be a problem since the web is packed with solutions and examples for exactly this. I googled and looked at hit ~100 and it described it just fine.

I already know the solution. This is just a challenge question. But i bet most of these sites point out the inner product as the solution which is not correct and will lead people to compute the wrong angle 50% of the time.
jojoh

JGO Knight

Medals: 5
Projects: 7

games4j.com

 « Reply #6 - Posted 2007-03-07 12:10:08 »

That reduces the answer to two complementary angles but we still need to find a way to know which one it is. There is only one angle between two vectors in a Cartesian Coordinate system and there's only one method to find this angle that works for all dimensions.

Not quite sure I follow you. Since we are talking about angle between angles then we don't care about clockwise counterclockwise (in 3d there is no such thing anyway). So say that there is an angle = 170 between the vectors, then there would also be an angle =190, just on the other side. Which one is correct? Depends on what you are looking for.

However there's a much faster way for 2D vectors. Do you know what it is?

I already know the solution. This is just a challenge question. But i bet most of these sites point out the inner product as the solution which is not correct and will lead people to compute the wrong angle 50% of the time.
In 2D you typically want to know the angle from a vector relative to another vector. I just used (without much pondering) brute force and calculated the angle for each vector and subtracted them (just did that in a game). Not sure if that is faster than what KILER described. If you have another faster way of finding the angle of a vector relative to another and that proves most of known techniques to be wrong, then please share!!! If what you use is not on the web, then we probably wonÂ´t be able to guess either.

K.I.L.E.R

Senior Devvie

Java games rock!

 « Reply #7 - Posted 2007-03-07 12:17:27 »

I never directly work with angles.

acos(1)
-5.313886335150516808261004276581286123443877333843750081075849201e-85

Which in effect is actually supposed to be 0.

I'm sure alternatives can be used within a given context. Why don't you just use differential equations to compute the angle if that's what you're really after?
There are hundreds of ways to derive the same thing via alternative methods.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed.
zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #8 - Posted 2007-03-07 13:23:02 »

Not quite sure I follow you. Since we are talking about angle between angles then we don't care about clockwise counterclockwise (in 3d there is no such thing anyway). So say that there is an angle = 170 between the vectors, then there would also be an angle =190, just on the other side. Which one is correct? Depends on what you are looking for.

Wait, theres only one angle between two vectors if you use a Cartesian Referential because the sign of the angle counts here. There's no other way to beat around this bush. This means that in a CR we have a linear space extended with two operations between vectors called the inner product (the dot product in 2d spaces) and an the outer product (also called the cross product with 2d vectors).

Quote
In 2D you typically want to know the angle from a vector relative to another vector. I just used (without much pondering) brute force and calculated the angle for each vector and subtracted them (just did that in a game).

Since nobody gave the right answer heres the two solutions. The first is to use the atan2 function but it only works with 2d vectors. The atan2 function is used to obtain the angle when we now the y and x coordinate. It's similar to use atan(y/x) but it also works for the II and III quadrants of the angle (ie if x is negative or zero).

Notice that the angle of a vector is zero when the vector is pointing towards the x-axis positive direction in a 2d CR. The angle between v1 and v2 is the angle that when rotating v1 will make it point in the direction of v2. If we don't get the right sign for the rotation it will point in the wrong direction.

So if we have two vectors v1=(v1_x, v1_y) and v2=(v2_x, v2_y) we simply do this:

angle=atan2(v2_y, v2_x) - atan2(v1_y, v2_x) OR atan2(v2_y, v2_x) = angle + atan2(v1_y, v1_x)

It's clear that if you add 'angle' to the angle of v1 you obtain the angle of v2.

For vectors of any dimension one of the steps is to obtain the inner product to get the cos of the angle. The other step is to know the sign of the angle or better yet we get a 3rd vector that will work as the axis-angle of rotation.

The solution is to obtain the absolute value of the angle = acos ( (v1 . v2) / ( |v1||v2| ) ) , then obtain the outer product u = norm ( v1 * v2 ) . We this we get the an axis-angle aa = (ux, uy, uz, angle) that can then be converted into a quaternion or an orthogonal matrix to do the rotation.

Check out this site if you want to know more:
http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
Kova

Senior Devvie

 « Reply #9 - Posted 2007-03-07 16:17:15 »

hmm... didn't read the article yet, can you tell me if this is correct then?
(i,j) is first point, (getPosX(), getPosY()) is second point

 1  2  3  4 `            adjacent = i - getPosX();            opposite = j - getPosY();            hypotenuse = (float)Math.hypot(adjacent, opposite);             kick_angle = (opposite > 0) ? (float)Math.acos(adjacent/hypotenuse) : (float)(2*Math.PI - Math.acos(adjacent/hypotenuse));`

...so is atan2 faster then this? better maybe? As I'm a mathematician, I didn't read any tutorial, just skeched it on paper and wrote this.
jojoh

JGO Knight

Medals: 5
Projects: 7

games4j.com

 « Reply #10 - Posted 2007-03-07 16:34:55 »

Wait, theres only one angle between two vectors if you use a Cartesian Referential because the sign of the angle counts here.

OK, we might not interpret the lingo in the same way. "The angle between vector 1 and vector 2 is -45 degrees" seems very odd to me. If you are talking about a vector relative to another vector then I agree on negative angles. It is the same as distance. If you have two apples on the table and they are 10 cm apart, and you move the right apple 20 cm to the left, would you say that the distance between the apples are -10cm??? I wouldn't.

Wait, theres only one angle between two vectors if you use a Cartesian Referential because the sign of the angle counts here.

This is sort of interesting. As I said before, I don't think that negative applies when you are talking about "between", but even so you still naturally have two angles between the two vectors. Say that you have two vectors with 150 degrees between them. Rotate on vector 20 degrees away, and you have 170 degrees between them. Movie it another 20 degrees. What do you say is the angle between the two vectors?

You also prove this very nicely with your code:

Since nobody gave the right answer heres the two solutions. The first is to use the atan2 function but it only works with 2d vectors. The atan2 function is used to obtain the angle when we now the y and x coordinate. It's similar to use atan(y/x) but it also works for the II and III quadrants of the angle (ie if x is negative or zero).

Notice that the angle of a vector is zero when the vector is pointing towards the x-axis positive direction in a 2d CR. The angle between v1 and v2 is the angle that when rotating v1 will make it point in the direction of v2. If we don't get the right sign for the rotation it will point in the wrong direction.

So if we have two vectors v1=(v1_x, v1_y) and v2=(v2_x, v2_y) we simply do this:

angle=atan2(v2_y, v2_x) - atan2(v1_y, v2_x) OR atan2(v2_y, v2_x) = angle + atan2(v1_y, v1_x)

It's clear that if you add 'angle' to the angle of v1 you obtain the angle of v2.
This is incidentally just a longwinded way of describing what I just stated before
...calculated the angle for each vector and subtracted them...
Just another way of saying: "If you want to know angle between two vectors, then calculate the angle of the two vectors and then calculate the difference"

Anyway, your code will give two different answers for vectors with same angel between them:

 1 `      System.out.println("angle1 = "+(Math.atan2(1, 3) - Math.atan2(-1, 3)));`

Here we calculate the angle between the the two vectors, and it works just fine:
angle1 = 0.6435011087932844

If we rotate both vectors 90 deg then we should have the same angle between them, right?
 1  2 `      System.out.println("angle1 = "+(Math.atan2(1, 3) - Math.atan2(-1, 3)));      System.out.println("angle2 = "+(Math.atan2(3, -1) - Math.atan2(3, 1)));`

Cool, it still works:
angle1 = 0.6435011087932844
angle2 = 0.6435011087932845

OK, lets do this for 90, 180 and 270 degrees rotation:
 1  2  3  4 `      System.out.println("angle1 = "+(Math.atan2(1, 3) - Math.atan2(-1, 3)));      System.out.println("angle2 = "+(Math.atan2(3, -1) - Math.atan2(3, 1)));      System.out.println("angle3 = "+(Math.atan2(-1, -3) - Math.atan2(1, -3)));      System.out.println("angle4 = "+(Math.atan2(-3, 1) - Math.atan2(-3, -1)));`

Result:
angle1 = 0.6435011087932844
angle2 = 0.6435011087932845
angle3 = -5.639684198386302
angle4 = 0.6435011087932845

So there you proved it yourself.

The angle between v1 and v2 is the angle that when rotating v1 will make it point in the direction of v2.

You can obviously rotate v1 clockwise n degrees to make it point towards v2 or 360 - n degrees counterclockwise.

jojoh

JGO Knight

Medals: 5
Projects: 7

games4j.com

 « Reply #11 - Posted 2007-03-07 17:03:19 »

...so is atan2 faster then this? better maybe? As I'm a mathematician, I didn't read any tutorial, just skeched it on paper and wrote this.
I think that you are calculating the angle of the line segment defined by the two points rather than the angle between two vectors. I just skimmed through the code so I might be wrong... The lingo can be very confusing.

atan2() does what I think your two last lines does, just wrapped up neatly, so I would go with atan2(). No danger of division by zero either, as your code exposes.

zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #12 - Posted 2007-03-07 17:21:24 »

 1  2  3  4 `            adjacent = i - getPosX();            opposite = j - getPosY();            hypotenuse = (float)Math.hypot(adjacent, opposite);             kick_angle = (opposite > 0) ? (float)Math.acos(adjacent/hypotenuse) : (float)(2*Math.PI - Math.acos(adjacent/hypotenuse));`

...so is atan2 faster then this?

You should always use atan2 an hypot whenever you want to get polar coordinates from rectangular coordinates (that is the angle and the radius). atan2 takes the same amount of time to compute than any other trig function. hypot is much faster than doing Math.sqrt(x*x + y*y).

OK, we might not interpret the lingo in the same way. "The angle between vector 1 and vector 2 is -45 degrees" seems very odd to me. If you are talking about a vector relative to another vector then I agree on negative angles. It is the same as distance. If you have two apples on the table and they are 10 cm apart, and you move the right apple 20 cm to the left, would you say that the distance between the apples are -10cm??? I wouldn't.

That's one of the biggest sources of confusion when talking about angles. When you measure the angle of a vector in a 2D Cartesian Coordinate System you are always measuring the angle relative to the x-axis unit vector.

This is sort of interesting. As I said before, I don't think that negative applies when you are talking about "between", but even so you still naturally have two angles between the two vectors. Say that you have two vectors with 150 degrees between them. Rotate on vector 20 degrees away, and you have 170 degrees between them. Movie it another 20 degrees. What do you say is the angle between the two vectors?

You have a point here, the word between was an ambiguous choice of words. I need o say what vector should be taken as the base vector for the rotation.

But you have to be careful with signs here. For example -90 degrees is not the same as 90 degrees (just negating the angle won't work). When you normalize -90 to the range of [0;360] the right answer is 360-90=270 degrees.
Kova

Senior Devvie

 « Reply #13 - Posted 2007-03-07 19:57:55 »

I think that you are calculating the angle of the line segment defined by the two points rather than the angle between two vectors. I just skimmed through the code so I might be wrong... The lingo can be very confusing.

atan2() does what I think your two last lines does, just wrapped up neatly, so I would go with atan2(). No danger of division by zero either, as your code exposes.

yeah, it's the angle between 2 points, but isn't that same thing? Angle stays the same...
Yeah, I will change to atan2() so I don't get division by zero if I accidently compare 2 identical points.

I also agree on angle between [0..360> (360 exclusive, as 0 is 360)

And sorry, my code calculates absolute angle in Cartesian Coordinate System, not angle between 2 points (relative angle).
jojoh

JGO Knight

Medals: 5
Projects: 7

games4j.com

 « Reply #14 - Posted 2007-03-07 22:13:33 »

yeah, it's the angle between 2 points, but isn't that same thing? Angle stays the same...
Yeah, I will change to atan2() so I don't get division by zero if I accidently compare 2 identical points.

A vector is defined by a direction and magnitude. This is typically done by specifying angle (from the x-axis), and the length of the vector, or (what we are talking about here) by specifying a point in space and the vector is from origo to the point. You can naturally convert between the two using cos and sin and atan. Or as you did hypot and acos, but that is a bit of a detour I think.

What you calculated was the direction from point 1 to point 2. We are looking for the differences in the angles. So you could change your code to first calc ang1 = (0,0) to (i,j) and ang2 = (0,0) to (getPosX(), getPosY()). Then calc ang2 - ang1 and that should be the answer. But
 1 `Math.atan2(i, j) - Math.atan2(getPosX(), getPosY())`
is in my opinion a more elegant solution.

K.I.L.E.R

Senior Devvie

Java games rock!

 « Reply #15 - Posted 2007-03-08 05:50:17 »

I wonder why that's yet to happen to me? Oh! I now what I'm doing.
Sorry but the dot product is defined as above. You seem to be having trouble modelling a situation by the looks of it, you obviously don't know what you are talking about or the solution given by reading your above posts.

Quote
I already know the solution. This is just a challenge question. But i bet most of these sites point out the inner product as the solution which is not correct and will lead people to compute the wrong angle 50% of the time.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed.
zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #16 - Posted 2007-03-08 18:32:55 »

I wonder why that's yet to happen to me? Oh! I now what I'm doing. Smiley
Sorry but the dot product is defined as above. You seem to be having trouble modelling a situation by the looks of it, you obviously don't know what you are talking about or the solution given by reading your above posts.

And i have explained why the dot product is NOT the right choice and even pointed a site that explains it more clearly. Feel free to discuss that or don't.
K.I.L.E.R

Senior Devvie

Java games rock!

 « Reply #17 - Posted 2007-03-08 20:52:25 »

If you want to stick to doing this some other way that's fine, however I'm sticking to my dot products and differential manifolds.
It's obvious that I cannot tell what you are asking by the last several posts.

Why would you use the dot product and why did you ask how to calculate the dot product when it's not what you're after?

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed.
zingbat

Senior Devvie

Medals: 1

Java games rock!

 « Reply #18 - Posted 2007-03-08 22:07:21 »

Are we reading the same thread here? Check out the topic of this thread and my answers. I hope that you at least accept that your first answer (the dot product) is not enough to answer the question "what is the angle between vector v1 and v2" and thus the reason of this discussion and the link i provided.

I don't see what your differential manifold reference has to do with a problem related to an euclidean space. I'm only making this thread to help people not fall into some common pitfalls in linear algebra.
K.I.L.E.R

Senior Devvie

Java games rock!

 « Reply #19 - Posted 2007-03-09 04:14:29 »

Sorry.
I'm a f'ing idiot, lets move on.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed.
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 ClaasJG (46 views) 2015-04-30 20:33:25 Riven (26 views) 2015-04-30 13:25:12 ClaasJG (48 views) 2015-04-27 13:36:51 BurntPizza (52 views) 2015-04-23 03:42:11 theagentd (53 views) 2015-04-22 16:23:07 Riven (66 views) 2015-04-16 10:48:47 Duke0200 (79 views) 2015-04-16 01:59:01 Fairy Tailz (62 views) 2015-04-14 20:13:12 Riven (64 views) 2015-04-12 21:36:37 bus hotdog (90 views) 2015-04-10 02:39:32
 theagentd 27x BurntPizza 20x Spasi 16x kingroka123 11x alwex 11x Hanksha 10x wessles 10x Ecumene 8x ra4king 8x EgonOlsen 8x princec 7x kevglass 6x chrislo27 5x Riven 5x trollwarrior1 5x KevinWorkman 5x
 List of Learning Resources2015-05-05 10:20:32How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org