Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions How to limit a layer’s position to a circular zone

  • How to limit a layer’s position to a circular zone

    Posted by Romain Charles on May 7, 2018 at 1:13 pm

    Hi everybody,

    I would like to allow layer’s positions only inside a circle, as if the layer was linked to an invisible rope.
    It is easy to limit positions to a square with the function clamp(), but I can’t find a solution with a circle.

    How can I do ?

    Romain Charles replied 8 years ago 3 Members · 6 Replies
  • 6 Replies
  • Andrei Popa

    May 7, 2018 at 3:27 pm

    center = [960,540]
    maxDistance =100;
    if (length(center,position)>maxDistance) center + maxDistance*(position-center)/length(center,position) else value

    However, if you go too far outside, the layer will act a bit strange before you get its position back inside the circle. The code was taken from here and altered a bit to fit your situation.

    Andrei
    My Envato portfolio.

  • Dan Ebberts

    May 7, 2018 at 3:43 pm

    Here’s a way to do it with vectors:

    center = [500,400];
    radius = 200;
    v = position – center;
    length(v) > radius ? center + normalize(v)*radius : value

    Dan

  • Romain Charles

    May 7, 2018 at 3:44 pm

    Thank you very much, I spent my entire day trying to find a solution !
    You’re the best !

  • Romain Charles

    May 7, 2018 at 4:22 pm

    Thank you too Dan, that gives me the occasion to work my javascript 😉

  • Romain Charles

    May 8, 2018 at 2:48 pm

    Hello, this is how I used your expression to work better on duik rigging.
    I lock the controller on the members.
    The expression is applied to the controller position.
    Thanks to the both of you !

    // layers relationships : member C parented to memberB parented to memberA parented to control

    memberA=thisComp.layer("cuisse droite");
    memberB=thisComp.layer("patte arrière droite");
    memberC=thisComp.layer("mollet arrière droite");
    control=thisComp.layer("corps");

    function getWorldPos(L){
    return L.toWorld(L.anchorPoint);
    }

    distA = length(getWorldPos(memberA),getWorldPos(memberB));
    distB = length(getWorldPos(memberB),getWorldPos(memberC));
    radius = distA+distB;

    // if the anchorPoint of the control layer is no [0,0]
    center = memberA.transform.position
    -corps.transform.anchorPoint;

    position = transform.position;
    v = position - center;
    length(v) > radius ? center + normalize(v)*radius : value

  • Romain Charles

    May 8, 2018 at 10:40 pm

    Update

    memberA=thisComp.layer("épaule droite");
    memberB=thisComp.layer("patte avant droite");
    memberC=thisComp.layer("mollet avant droite");

    function getWorldPos(L){
    return L.toWorld(L.anchorPoint);
    }

    distA = length(getWorldPos(memberA),getWorldPos(memberB));
    distB = length(getWorldPos(memberB),getWorldPos(memberC));
    radius = distA+distB;

    center = getWorldPos(memberA);
    pos = getWorldPos(thisLayer);

    v = pos - center;
    length(v) > radius ? center + normalize(v)*radius : value

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