Creative Communities of the World Forums

The peer to peer support community for media production professionals.

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 pm

    Anyone 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,
    Jamie

    JimJam•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 pm

    I’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 pm

    Thanks 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 pm

    Yesterday, 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 pm

    It 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 pm

    Hi 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.

    5482_2dlinestuffh264.mov.zip

    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 pm

    I 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 am

    Thanks 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,
    Jamie

    JimJam•Graphics
    https://www.jimjamgraphics.com/

  • James Hazael

    April 8, 2016 at 3:40 am

    I 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 pm

    I 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 pm

    Thanks, that looks much simpler than the way I eventually did it.

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy