Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Wiggle across one axis with no overlap

  • Wiggle across one axis with no overlap

    Posted by John Burgess on April 12, 2021 at 10:20 pm

    Hi,

    Is it possible for multiple layers to randomly move across a single axis and not touch or overlap each other. My first instinct was to use a wiggle but I can’t seem to find anything for it to detect other layers, is this possible using something more advanced?

    Gif of what I am trying to achieve.

    Thanks.

    Filip Vandueren replied 3 years, 10 months ago 4 Members · 7 Replies
  • 7 Replies
  • Dan Ebberts

    April 13, 2021 at 7:00 am

    I don’t know if this will help or not, but it might get you started. If you create a text layer (named “text”) with this as the source text expression:

    w = [];

    n = 5;

    for (i = 1; i <=5; i++){

    seedRandom(i,true);

    w.push((position.wiggle(1,1000)-position)[0]);

    }

    w.sort((a,b)=>a-b)

    and then create 5 tall skinny solids (below the text layer in the layer stack, layers 2 – 6), each with this position expression:

    x = thisComp.layer("text").text.sourceText.split(",")[index-2];

    value + [x,0]

    You should get horizontal random movement but the layers won’t cross. You can turn off the eyeball for the text layer (or move it outside the comp boundary).

  • Andrei Popa

    April 13, 2021 at 7:13 am

    Here is an idea.

    I made the first line wiggle between mid of comp and 0. Then, for each of the following, I made them wiggle from the previous line to the end of the comp. Make sure to set the x positions of the lines to 0, otherwise you will have to subtract it from the wiggle and that is just unnecessary computing.

    On the first line put this expression(after you set the first value of position to 0):

    startPos = thisComp.width/4;
    freq = 1;
    wiggDistance = startPos;
    [startPos+wiggle(freq,wiggDistance)[0],value[1]]

    Duplicate it and then, on the second line put this expression:

    prevPos = thisComp.layer(index+1).position[0];
    wiggDistance = (thisComp.width-prevPos)/2;
    startPos = prevPos+wiggDistance;
    freq = 1;
    [startPos+wiggle(freq,wiggDistance)[0],value[1]]

    Now, you can duplicate this second line for as many times as you want. You may want to diminish the wiggDistance for the first line if you add a lot of line, because the left part of the comp will have less action.

  • John Burgess

    April 14, 2021 at 8:37 pm

    Thanks for your reply Andrei,

    Looks like there is still an overlap, i’m getting the following error on the last line in the stack. Any ideas?

  • John Burgess

    April 14, 2021 at 9:50 pm

    Thanks for your reply Dan, I’m still getting a bit of overlap any thoughts?

  • Andrei Popa

    April 17, 2021 at 1:10 pm

    The lines should go upwards, in the order they get when you press ctrl+d to duplicate them. Something like:

    Line4

    Line3

    Line2

    Line 1

    But I think Dan’s solution is better because mine tends to stack the lines on the right side if there are too many.

  • Filip Vandueren

    April 19, 2021 at 10:03 am

    Don’t know if it’s related, but there’s a slight problem with wiggle(): if you do a wiggle(2,50) it can produce values that are slightly out of the bounds of [-50,50].

    A more precise bounded way can be with noise(), like this:

    n=noise([time*2,index*123])*50; 

    This will keep the random values exactly between -192 and +192.

    the time *2 is roughly equivalent to the frequency, the index*123 makes the noise unique for each layer. if you lower that value, then all layers become more and more correlated.

  • Filip Vandueren

    April 19, 2021 at 10:22 am

    Here’s my approach building on Dan’s solution (and also on Andrei’s):

    expression for the text-layer named “list”:

    <pre style=”position: relative;”>

    list=[];

    runningTotal = 0;

    for (i=0; i<5; i++) {

    n=linear(noise([time, i*123]),-1,1,0.01,1);

    runningTotal+=n;

    list.push(runningTotal);

    }

    list.map(e => e * thisComp.width/runningTotal).slice(0,4);

    <div class=”open_grepper_editor” title=”Edit & Save To Grepper”></div>

    The linear() is there to makes absolutely sure there’s no overlap, as it turns out, even the noise() function can go slightly out of bounds…

    And each vertical line’s position gets this expression:

    <pre style=”position: relative;”>list = thisComp.layer(“list”).text.sourceText.split(“,”);
    [list[index-1],value[1]];<div class=”open_grepper_editor” title=”Edit & Save To Grepper”></div>

    (assuming the indexes of the 4 line layers are 1-4)

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