radiusA = 20; //Radius of helper grove [cm] height_main = 20; //Height of helper grove [cm] Nturns = 1; //How much turns should the helper have. //Slide size sideX = 2; sideY = 2; turns = 360*Nturns; //Smoothness smoothness = 5; $fn = 20; thickness = 1.0; offset_between_parts=1.5; skirtZ = 0.1*(thickness*2.0); module line3D(p1, p2, thickness) { hull() { translate(p1) sphere(thickness / 2); translate(p2) sphere(thickness / 2); } } module polyline3D(points, thickness) { module polyline3D_inner(points, index) { if(index < len(points)) { line3D(points[index - 1], points[index], thickness, fn); polyline3D_inner(points, index + 1); } } polyline3D_inner(points, 1); } points = [ for(a = [0:smoothness:360 * Nturns]) [radiusA * cos(a), radiusA * sin(a), height_main / (360 / smoothness) * (a / smoothness)] ]; color("red"){ difference(){ polyline3D(points, thickness); translate([-radiusA-sideX, -radiusA-sideY, +height_main/2+skirtZ*4]){ cube([radiusA*2+sideX*2,radiusA*2+sideY*2,height_main/2+skirtZ*4]); } } } color("blue"){ translate([0, radiusA*2 +offset_between_parts, -height_main/2]){ difference(){ polyline3D(points, thickness); translate([-radiusA-sideX, -radiusA-sideY, -skirtZ*4]){ cube([radiusA*2+sideX*2,radiusA*2+sideY*2,height_main/2+skirtZ*4]); } } } }