Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions Collision detection on Shapes

  • Collision detection on Shapes

  • Justin Productions

    September 21, 2022 at 3:59 am

    Hey guys,

    Context:

    – I have a Shape Layer containing 161 shapes (squares), all of which have their Position property animated.

    – I have 2 other Shape Layers. Each of those just contains 1 big colored circle.

    Goal:

    My intent is to have my 2 Circles act as some type of “Radial Effectors”, where they immediately change the color of the squares (which could be perceived as clones) they happen to intersect with.

    So it’s as if the squares had 2 states: if they’re not intersecting with any of the Circles, their color is black. If they do intersect with the circles, then their Color property changes to the color of the Circle they’re intersecting with.

    All of the above has to take into account the fact that my clones and Circles are in constant movement.

    Progress:

    I have tried/bought every Effector plugin on AEScripts and to my big surprise, none of them have allowed me to meet this goal. Some of them came very close, but after discussing with their authors and reading every plugin’s docs, it just doesn’t seem feasible.

    I have since taken upon myself to carefully study Dan Ebbert’s Collision Detection script and tried to apply it to all of my Shapes, but I’m a bit lost when it comes to these questions:

    – Should I apply the expression on every single square?

    – How do I translate the calculation of the bounding box of a layer to the one of a Shape layer?

    Final notes:

    I have trimmed all the fat from my project file and just kept the essential before attaching it to this post. If you guys would be so kind to take a peek, I would be immensely grateful.

    I feel like I can figure some things on my own, but for now I feel in great need of any guidance.

    Thank you so very much!

  • Dan Ebberts

    September 21, 2022 at 4:35 am

    Hmmm…. You might have a fighting chance if each of your squares was a separate layer. Then you could use sourceRectAtTime() to get the bounding box of the square and use the bounding box of each circle to calculate its center and radius and then calculate if there’s a collision. I don’t think you have the right tools to do it with individual shapes in the same shape layer.

    Scratch all that… you do have size and location of each square, and that may be enough. I’ll be back…

  • Dan Ebberts

    September 21, 2022 at 5:16 am

    I think this gets pretty close. If the center of the square gets inside a circle, it should pick up that circle’s color, otherwise black. To make it work if any part of the square touches the circle would take a bunch more code. You might also need to decide what to do if the center of the square is inside both circles. But it’s an encouraging start, I think.

    C1 = thisComp.layer("RADIAL EFFECTOR 01");
    C2 = thisComp.layer("RADIAL EFFECTOR 02");
    r1 = C1.sourceRectAtTime(time,false);
    radius1 = r1.width/2;
    p1 = C1.toComp([r1.left+r1.width/2,r1.top+r1.height/2]);
    r2 = C2.sourceRectAtTime(time,false);
    radius2 = r2.width/2;
    p2 = C2.toComp([r2.left+r2.width/2,r2.top+r2.height/2]);
    myPos = thisProperty.propertyGroup(3)("Transform")("Position").value;
    d1 = length(toComp(myPos),p1);
    d2 = length(toComp(myPos),p2);
    if (d1<radius1)
    C1("Contents")("Ellipse 1")("Contents")("Fill 1")("Color")
    else if (d2 < radius2)
    C2("Contents")("Ellipse 1")("Contents")("Fill 1")("Color")
    else
    [0,0,0,1]
  • Justin Productions

    September 21, 2022 at 5:53 pm

    Dan,

    This snippet of code is better than “pretty close”. It’s exactly what I’ve envisioned. I also made sure to study the code and understand it so I could make small tweaks of my own (see additions below). Thank you so very much! I appreciate it immensely.

    Additions:

    I wanted to “fake” the Lighten color mode on the clones that were simultaneously intersected by the 2 Radial effectors. To do so, I combined Dan’s code with Oleg Pirogov’s solution to mix 2 color vectors. The result is as follows:

    function lighten(r1, r2){
    if(r1 <= r2)
    return r2
    else if(r1 > r2)
    return r1
    };
    C1 = thisComp.layer("RADIAL EFFECTOR 01");
    C2 = thisComp.layer("RADIAL EFFECTOR 02");
    r1 = C1.sourceRectAtTime(time,false);
    radius1 = r1.width/2;
    p1 = C1.toComp([r1.left+r1.width/2,r1.top+r1.height/2]);
    r2 = C2.sourceRectAtTime(time,false);
    radius2 = r2.width/2;
    p2 = C2.toComp([r2.left+r2.width/2,r2.top+r2.height/2]);
    myPos = thisProperty.propertyGroup(3)("Transform")("Position").value;
    d1 = length(toComp(myPos),p1);
    d2 = length(toComp(myPos),p2);
    if (d1<radius1 && d2 < radius2){
    C1_color = C1("Contents")("Ellipse 1")("Contents")("Fill 1")("Color");
    C2_color = C2("Contents")("Ellipse 1")("Contents")("Fill 1")("Color");
    a2=C2_color[3];
    a1=C1_color[3];
    a=a2+a1-a2*a1;
    B = [lighten(C1_color[0], C2_color[0]), lighten(C1_color[1], C2_color[1]), lighten(C1_color[2], C2_color[2])];
    aC=(a - a2)*C1_color+(a2)*((1-a1)*C2_color+a1*B);
    z=[aC[0]/a, aC[1]/a, aC[2]/a, a];
    }else if (d1 < radius1){
    C1("Contents")("Ellipse 1")("Contents")("Fill 1")("Color")
    }else if (d2 < radius2){
    C2("Contents")("Ellipse 1")("Contents")("Fill 1")("Color")
    }else{
    [0,0,0,1]
    }

    Dan, I can’t thank you enough for your assistance. I’ve been a member of CC since 2005 and I can’t tell you how grateful I am for all that you’ve done, for me and other members of this community.

    Thanks a million once again.

Viewing 1 - 4 of 4 posts

Log in to reply.

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