module vine(number, diameter, decrease, target, rateOfChange, chanceOfFork, chaos, chanceOfForkIncrease, seed = 1) { function rnd(s) = rands(0,1,1,s)[0]; if (number > 0) { union() { polygon([ [-diameter / 2,0], [(-diameter * decrease)/2, 3], [(diameter * decrease)/2, 3], [diameter / 2,0] ]); translate([0,3]) circle(diameter * decrease / 2); //cylinder(3, diameter, diameter * decrease); //translate([0,0,3]) sphere(diameter * decrease); } rndFork = rands(0,1,1,seed)[0]; fork = rndFork < chanceOfFork; forks = fork ? [0,-45] : [0]; rndForks = rands(0,1,len(forks),rndFork); rndForks2 = rands(0,1,len(forks),rndForks[len(rndForks) - 1]); rndForks3 = rands(0,1,len(forks),rndForks[len(rndForks2) - 1]); rndForks4 = rands(0,1,len(forks),rndForks[len(rndForks3) - 1]); for (i = [0:len(forks)-1]) { turn = rateOfChange * rndForks[i] * sign(target) + forks[i] * rndForks2[i] + (rndForks3[i] - .5) * chaos; translate([0,3,0]) rotate([0,0,turn]) vine( number - 1, diameter * decrease, decrease, target - turn, rateOfChange, //fork ? chanceOfFork / 2 : chanceOfFork, fork ? 0 : chanceOfFork + chanceOfForkIncrease, chaos, chanceOfForkIncrease, rndForks4[i] ); } } } /* $fn=16; linear_extrude(height = 10, center = true, convexity = 10) vine( number = 20, diameter = 3, decrease = .9, target = 0, rateOfChange = 4, chanceOfFork = 0, chanceOfForkIncrease = .116, chaos = 60, seed=3 ); */