Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Shape layer expression query.

Explorer ,
Dec 18, 2021 Dec 18, 2021

Hello.

I am still trying to learn expressions in after effects. So I was stuck with something and I thought might as well ask. So I've uploaded a screenshot. My requirement is the small red shape layers should wiggle inside the big circle shape layer and should not go out of it. If it tries to go out it should like collide with the shape layer and stay inside. Is there an expression or script that allows me to wiggle but also like clamps the region of the small red shape layer to the region of the circle. 

TOPICS
Expressions , How to , Scripting
1.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 18, 2021 Dec 18, 2021

Is it doable? Yes, just not with a "dumb" wiggle. Since there is no simple collision function in the expression engine, you'd have to check the position against the parametric definition of a circle with sinus and cosinus and then it turns into quite some math. A simplification of this might be to wiggle along the radius of the circle, but then of course the motion looks different. So there you have it. It would take soem time to sit down and craft the code. Other than that if you really just want some round blobs to bounce off a mask in 2D give good old Particle Playground a try.

 

Mylenium

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 18, 2021 Dec 18, 2021

I would start with Dan Ebbert's Collision Detection from motionscript.com

 

In the example, Dan is controlling opacity, but you could use the same basic math to control the position and force another move. I'm not saying that it would be simple, but it could be done.

 

Here's Dan's basic code:

function getMin(a, b, c, d){
  return Math.min(Math.min(a,b),Math.min(c,d));
}

function getMax(a, b, c, d){
  return Math.max(Math.max(a,b),Math.max(c,d));
}

function getBoundingBox(theLayer){
  bb = [];
  c1 = theLayer.toWorld([0,0]);
  c2 = theLayer.toWorld([theLayer.width,0]);
  c3 = theLayer.toWorld([theLayer.width,theLayer.height]);
  c4 = theLayer.toWorld([0,theLayer.height]);
  bb[0] = getMin(c1[0],c2[0],c3[0],c4[0]);
  bb[1] = getMin(c1[1],c2[1],c3[1],c4[1]);
  bb[2] = getMax(c1[0],c2[0],c3[0],c4[0]);
  bb[3] = getMax(c1[1],c2[1],c3[1],c4[1]);
  return bb;
}

function checkLayers(){
  cUL = [];
  cLR = [];
  for ( idx = 1; idx <= thisComp.numLayers; idx++){
    if (index == idx) continue;
    L = thisComp.layer(idx);
    if (! L.active) continue;
    BB = getBoundingBox(L);
    UL = [BB[0],BB[1]];
    LR = [BB[2],BB[3]];

    if (!(myLR[1] < UL[1] || LR[1] < myUL[1] ||
          myLR[0] < UL[0] || LR[0] < myUL[0])){

      cUL[1] = (myUL[1] < UL[1]) ? UL[1] : myUL[1];
      cUL[0] = (myUL[0] < UL[0]) ? UL[0] : myUL[0];
      cLR[1] = (myLR[1] < LR[1]) ? myLR[1] : LR[1];
      cLR[0] = (myLR[0] < LR[0]) ? myLR[0] : LR[0];

      for(i = cUL[0]; i <= cLR[0]; i++){
        for (j = cUL[1]; j <= cLR[1]; j++){
          if (sampleImage(fromWorld([i,j]))[3] > 0 &&
              L.sampleImage(L.fromWorld([i,j]))[3] > 0){

            return true;
          }
        }
      }
    }
  }
  return false;
}

myBB = getBoundingBox(thisLayer);
myUL = [myBB[0],myBB[1]];
myLR = [myBB[2],myBB[3]];

if (checkLayers()){ 100 }else{ 30 }

As I said, this is controlling opacity, but it could be set to trigger a change in direction.

 

The other option: Newton. If your time is worth $50/hr and it takes you 4 hours to figure out the code you have more than paid for Newton.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 18, 2021 Dec 18, 2021

If you make some assumptions, like the shape layers are centered (so thier shape transform anchor points and positions are [0,0], you can probably get away with something like this for the red dots shape position expression:

r = thisComp.layer("Shape Layer 1").content("Ellipse 1").content("Ellipse Path 1").size[0]/2;
w = wiggle(2,r);
if (length(w) > r){
  normalize(w)*r;
}else
  w
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 18, 2021 Dec 18, 2021
LATEST

I knew that Dan would come up with something brilliant.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines