// extrusion takes a list of polygons (list of points in 3d space) and connects these into one big polyeder module extrusion(points){ //points[0] must have its points ordered clockwise n = len(points); k = len(points[0]); points_new = [for(L = points) for(p = L) p]; faces = concat([[for(i = [0 : k-1]) i], [for(i = [1 : k]) (n*k)-i]], concat([for (i = [0 : n-2]) for (j = [0 : k-2]) [(i*k)+j+1, (i*k)+j, ((i+1)*k)+j, ((i+1)*k)+j+1]], [for (i = [0 : n-2]) [i*k,(i+1)*k-1,((i+2)*k)-1,(i+1)*k]])); polyhedron(points = points_new, faces = faces, convexity = 10); } //ctrl is a list containing 4 control points of the bezier curve. shape is polygon in the 2d plane which is being extruded. mod is a function [0,1] -> |R scaling the shape, mod_x in the x-direction (of the shape), mod_y in the y-direction. if partial is true, then the polyeder is rendered in slices with length given by merlon and gap size given by gap, section defines the number of sections the bezier curve is broken into module bezier_extrude(ctrl, shape, mod = function (t) 1, mod_x = function(t) 1, mod_y = function (t) 1, partial = false, merlon = 1, gap = 1, sections = 128){ B_0 = ctrl[0]; B_1 = 3*(-ctrl[0] + ctrl[1]); B_2 = 3*(ctrl[0] - 2*ctrl[1] + ctrl[2]); B_3 = -ctrl[0] + 3*(ctrl[1] - ctrl[2]) + ctrl[3]; function bezier(t) = B_0 + t*B_1 + (t^2)*B_2 + (t^3)*B_3; Bn_0 = [B_1.y,-B_1.x]; Bn_1 = [2*B_2.y,(-2)*B_2.x]; Bn_2 = [3*B_3.y,(-3)*B_3.x]; function normal(t) = Bn_0 + t*Bn_1 + (t^2)*Bn_2; slices = [for (i = [0 : sections]) let (t = i/sections, p = bezier(t), normal = normal(t), n = normal/norm(normal)) [for (v = shape) [p.x+(mod(t) * mod_x(t) * n.x * v.x),p.y+(mod(t) * mod_x(t) * n.y * v.x), mod(t) * mod_y(t) * v.y]]]; if(partial){ for(i = [0 : merlon+gap : sections-merlon]){ extrusion([slices[i],slices[i+merlon]]); } } else{ extrusion(slices); } } //some thing to play around with shape = [[0,0.5],[0.8,0],[0.5,-1],[-0.5,-1],[-0.8,0]]; ctrl = [[0,0],[0,20],[20,20],[20,0]]; wave1 = function (x) 0.75+0.25*cos(8*360*x); wave2 = function (x) 0.75+0.25*sin(8*360*x); bezier_extrude(ctrl = ctrl, shape = shape, mod_x = wave1, mod_y = wave2, partial = true, merlon = 3, gap = 1, sections = 128);