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

Make switch/case expression choose any option except the current one?

Explorer ,
Apr 24, 2020 Apr 24, 2020

After doing the Workbench L-System tutorial, I've been trying to modify the script so that the path doesn't double back on itself. My goal is create a script generated paths that sort of looks like growing circuitry. Below is the code from the tutorial. I believe this involves making the switch(r) function remember it's current case and choose any case that isn't that. However, after researching expressions and javascript switch/case functions, this is clearly above my current coding ability. Anyone know how to solve this, or point me in the right direction? I'm a bit stumped. I've also attached a screenshot with the bits where the path backtracks on itself I'm trying to get rid of.

 

s = thisComp.layer("Controller").effect("Random Seed")("Slider");
n = thisComp.layer("Controller").effect("Steps")("Slider");
l = thisComp.layer("Controller").effect("Max Length")("Slider");
seedRandom(s, true);
var pts = [];
var x = y = 0;
pts.push([x,y]);
for(i = 0; i < n; i++) {
    var d = Math.floor(random(l));
    var r = Math.floor(random(4));
    switch(r) {
        case 0:
            x += d;
            break;
        case 1:
            y += d;
            break;
        case 2:
            x -= d;
            break;
        case 3:
            y -= d;
            break;
    }
    pts.push([x,y]);
}
createPath(pts, [], [], false);

Capture.JPG

TOPICS
Expressions , Scripting
7.2K
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 ,
Apr 24, 2020 Apr 24, 2020

Long and short: You wouldn't use switch() in such a scenario and simply refactor it with calssic if()else() statements. switch() may have better performance, but it doesn't have persistent branching, which is what your use case would need - only go to the next lower level if the parent levels are not identical. Another option might of course be to optimize the generated array after the fact and remove redundancies, but that would be equalyl complex and not offer much advantage over the other method.

 

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 ,
Apr 24, 2020 Apr 24, 2020

Try it this way:

 

s = thisComp.layer("Controller").effect("Random Seed")("Slider");
n = thisComp.layer("Controller").effect("Steps")("Slider");
l = thisComp.layer("Controller").effect("Max Length")("Slider");
var pts = [];
var x = y = 0;
pts.push([x,y]);
rPrev = 0;
for(i = 0; i < n; i++) {
    var d = Math.floor(random(l));
    var r = (rPrev + 3 + Math.floor(random(3)))%4;
    switch(r) {
        case 0:
            x += d;
            break;
        case 1:
            y += d;
            break;
        case 2:
            x -= d;
            break;
        case 3:
            y -= d;
            break;
    }
    pts.push([x,y]);
    rPrev = r;
}
createPath(pts, [], [], false);
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 ,
Apr 24, 2020 Apr 24, 2020

I left out the seedRandom(), and this is better anyway:

 

 

s = thisComp.layer("Controller").effect("Random Seed")("Slider");
n = thisComp.layer("Controller").effect("Steps")("Slider");
l = thisComp.layer("Controller").effect("Max Length")("Slider");
seedRandom(s,true);
var pts = [];
var x = y = 0;
pts.push([x,y]);
rPrev = Math.floor(random(4));
for(i = 0; i < n; i++) {
    var d = Math.floor(random(l));
    var r = (rPrev + 3 + Math.floor(random(3)))%4;
    switch(r) {
        case 0:
            x += d;
            break;
        case 1:
            y += d;
            break;
        case 2:
            x -= d;
            break;
        case 3:
            y -= d;
            break;
    }
    pts.push([x,y]);
    rPrev = r;
}
createPath(pts, [], [], false);

 

 

Dan

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
Explorer ,
Apr 30, 2020 Apr 30, 2020

Thanks Dan! I must admit that the math here is a bit beyond me at the moment. How would I adapt this for 8 cases? I've tried the following but without luck:

rPrev = Math.floor(random(8));
for(i = 0; i < n; i++) {
    var d = Math.floor(random(l));
    var r = (rPrev + 7 + Math.floor(random(7)))%8;
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 ,
Apr 30, 2020 Apr 30, 2020
LATEST

I'm making a guess as to what the other directions would be, but it could be something like this:

 

s = thisComp.layer("Controller").effect("Random Seed")("Slider");
n = thisComp.layer("Controller").effect("Steps")("Slider");
l = thisComp.layer("Controller").effect("Max Length")("Slider");
seedRandom(s,true);
var pts = [];
var x = y = 0;
pts.push([x,y]);
rPrev = Math.floor(random(8));
for(i = 0; i < n; i++) {
    var d = Math.floor(random(l));
    var r = (rPrev + 5 + Math.floor(random(7)))%8;
    switch(r) {
        case 0:
            x += d;
            break;
        case 1:
            x += d;
            y += d;
            break;
        case 2:
            y += d;
            break;
        case 3:
            x -= d;
            y += d;
            break;
        case 4:
            x -= d;
            break;
        case 5:
            x -= d;
            y -= d;
            break;
        case 6:
            y -= d;
            break;
        case 7:
            y -= d;
            x += d;
            break;
    }
    pts.push([x,y]);
    rPrev = r;
}
createPath(pts, [], [], false);

 

Dan

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