I want to write a more symmetric version (reflected along an axis) so it can be used with polyfolds and stuff, but it's based on the following code (which is only for the x-axis!):
uniform list (floats): AccCycle, CycleShift, AccEnd, AccStart
float Accordion (inout vec3 z) {
float zx=z.x;
float cycle=abs(AccCycle);
if (cycle<.06) {cycle=.06;}
float i=1.0; //why did he use a float here? :p
float cycleshift=abs(mod(CycleShift,abs(AccCycle)));
float cyclemod= (mod(abs(AccEnd-AccStart),AccCycle));
cyclemod=mod(cycle+cyclemod-cycleshift,cycle);
if ((cycle)>abs(AccEnd-AccStart)) {cycle=abs(AccEnd-AccStart);}
float rotdir=1.0;
if (AccEnd-AccStart<0.0) {
cycle=-cycle;
cyclemod=-abs(cyclemod);
cycleshift=-abs(cycleshift);
if (zx>AccStart) {
// do nothing
} else if (zx<AccStart && zx>(AccStart+cycleshift)) {
//first cycle!!!
zx=zx-(AccStart);
if (zx<(cycleshift/2.)) {
zx=cycleshift-zx+AccStart;
} else {zx+=AccStart;}
//done
}
else if (zx<(AccStart) && zx>(AccEnd-cyclemod)){
zx=zx-AccStart-cycleshift;
//i+=1.0;
rotdir*=-1;
while (zx<(cycle) && i<3000.0) {
zx-=cycle;i+=1.0;rotdir*=-1;
}
if (zx<(cycle/2.)) {
zx=cycle-zx+AccStart;//rotdir*=-1;
} else {zx+=AccStart;}
//done
}
else if (zx<(AccEnd- cyclemod) && zx>AccEnd) {
zx=AccEnd-zx;
if (zx<cyclemod/2.0) {
zx=cyclemod-zx+AccStart;
} else {
zx=zx+AccStart;
}
}
else if (zx<AccEnd) {
zx=zx-AccEnd+AccStart;
}
} else { //pos section AccEnd-AccStart >0
cycle=abs(cycle);
cyclemod=abs(cyclemod);
cycleshift=abs(cycleshift);
if (zx<AccStart) {
// do nothing
} else if (zx>AccStart && zx<AccStart+cycleshift) {
//first cycle!!!
zx=zx-AccStart;
if (zx>cycleshift/2.) {
zx=cycleshift-zx+AccStart;
} else {
zx+=AccStart;
}
} else if (zx>(AccStart) && zx<(AccEnd-cyclemod)){
zx=zx-AccStart-cycleshift; //i+=1.0;
rotdir*=-1;
while (zx>(cycle) && i<3000.0) {
zx-=cycle;i+=1.0;rotdir*=-1;
}
if (zx>(cycle/2.)) {
zx=cycle-zx+AccStart;//rotdir*=-1;
} else {zx+=AccStart;}
//done
}
else if (zx>(AccEnd- cyclemod) && zx<AccEnd) {
zx=AccEnd-zx;
if (zx>cyclemod/2.0) {
zx=cyclemod-zx+AccStart;
} else {
zx=zx+AccStart;
}
//i+=floor((AccEnd-cyclemod-AccStart)/cycle)+1.0;
}
else if (zx>AccEnd) {
zx=zx-AccEnd+AccStart;
//i+=floor((AccEnd-cyclemod-AccStart)/cycle)+2.0;
}
}
z.x=zx;
return z;
}
This version starts at a point you pick (AccStart), then cycles (up towards the midpoint of a cycle then back down to the beginning of the cycle if you're going in a positive direction, down towards the midpoint then back up to the beginning of the cycle if you're going in a negative direction) until you reach the end. The cycle shift shifts the location of the cycles, so you can introduce movement, or change something around a bit.
I'd like to make a similar function centered at a point along an axis for a symmetric version (extends out from a central point)... need to draw it on a piece of paper before I start coding I think.