Activity › Forums › Adobe After Effects Expressions › Calculating the angle between 2 vectors
-
Calculating the angle between 2 vectors
Posted by Jamie Bradshaw on February 19, 2013 at 4:05 pmAnyone here who can help me with this? My sleep-deprived brain is really struggling with it.
I have 3 points: A, B and C
I want to calculate the angle at point B that describes the angle between the two vectors AB and BC but takes the direction into consideration. For example the angle calculated is always anti-clockwise starting from AB and ending at BC.
I have used the cosine law to work out the angle if you treat ABC as a triangle, but I am struggling to know what catch I need to put in to see if I want to use the angle as is or use (360 – angle). Make sense?
Cheers,
JamieJimJam•Graphics
https://www.jimjamgraphics.com/James Hazael replied 10 years, 1 month ago 4 Members · 10 Replies -
10 Replies
-
Dan Ebberts
February 19, 2013 at 4:36 pmI’d do it like this:
a = thisComp.layer(“Null 1”).transform.position;
b = thisComp.layer(“Null 2”).transform.position;
c = thisComp.layer(“Null 3”).transform.position;v1 = normalize(a-b);
v2 = normalize(c-b);
angle = radiansToDegrees(Math.acos(dot(v1,v2)))Dan
-
Jamie Bradshaw
February 19, 2013 at 4:53 pmThanks Dan. That looks interesting. I’ve not come across dot() before… What does it do?
JimJam•Graphics
https://www.jimjamgraphics.com/ -
Paul Roper
February 19, 2013 at 5:04 pmYesterday, while investigating some vector maths, I came across the lookAt function in the AE help PDF (reading the manual?Wwho’d have thought it?!). It might also be of use to you, Jamie.
Here’s the cromulent section copied from the help:
lookAt(fromPoint, atPoint)
Return type: Array [3].Argument type: fromPoint and atPoint are Arrays [3].
The argument fromPoint is the location in world space of the layer you want to orient. The argument atPoint is the point in world space you want to point the layer at. The return value can be used as an expression for the Orientation property, making the z axis of the layer point at atPoint. This method is especially useful for cameras and lights. If you use this expression on a camera, turn off auto-orientation. For example, this expression on the Orientation property of a spot light makes the light point at the anchor point of layer number 1 in the same composition: lookAt(position, thisComp.layer(1).position)
– Paul
-
Dan Ebberts
February 19, 2013 at 5:04 pmIt gives you the dot product of two vectors. If the vectors are unit vectors (which is what normalize does), the dot product gives you the cosine of angle between the vectors.
Dan
[edit: changed “arc cosine” to “cosine”]
-
Jamie Bradshaw
February 19, 2013 at 5:55 pmHi Dan. Actually the same problem still exists. Although the dot product is a much cleaner way of doing it.
Here is a link to highlight the problem.
When B passes through AC the angle calculation breaks. I know that I want it to then be (360 – angle) I just don’t know what code to use to ‘catch’ it.
JimJam•Graphics
https://www.jimjamgraphics.com/ -
Dan Ebberts
February 19, 2013 at 6:29 pmI think you can do that with the vector cross product:
a = thisComp.layer(“Null 1”).transform.position;
b = thisComp.layer(“Null 2”).transform.position;
c = thisComp.layer(“Null 3”).transform.position;v1 = normalize(a-b);
v2 = normalize(c-b);
angle = radiansToDegrees(Math.acos(dot(v1,v2)));
if (cross(v1,v2)[2] < 0) angle = 360 – angle;Dan
-
Jamie Bradshaw
February 20, 2013 at 10:16 amThanks Dan, that worked.
I think I’ll need to invest some time to workout what cross(v1, v2) does. In the mean time I found this website that does a good job of explaining and visualising what the dot product is:
https://mines.lumpylumpy.com/Electronics/Computers/Software/Cpp/Graphics/Vector/DotProduct.php
Cheers,
JamieJimJam•Graphics
https://www.jimjamgraphics.com/ -
James Hazael
April 8, 2016 at 3:40 amI know it’s been awhile since this has been posted. But is there a way to make this work with nulls parented to separate layers. Something like the toWorld() Expression. Thanks.
-
Dan Ebberts
April 8, 2016 at 4:23 pmI haven’t tested this, but I think you would just change the first part like this:
a = thisComp.layer(“Null 1”).toWorld([0,0,0]);
b = thisComp.layer(“Null 2”).toWorld([0,0,0]);
c = thisComp.layer(“Null 3”).toWorld([0,0,0]);Dan
-
James Hazael
April 8, 2016 at 11:39 pmThanks, that looks much simpler than the way I eventually did it.
Reply to this Discussion! Login or Sign Up