// Parametric Bolt Maze // by seedwire // // Modify the maze array to change the paths through the maze. // "0" means no path, "1" means path... a complete path requires // adjacent "1"s from top to bottom. The left and right edges do // wrap around, so, beware! // Thanks MCAD! include include $fn=50; maze = [ [0,0,1,0,0,1,0,1,0,0], [0,0,1,0,0,1,0,1,1,1], [0,1,1,1,1,1,0,0,0,1], [0,1,0,0,0,1,0,0,1,1], [0,1,0,1,1,1,0,1,1,0], [1,1,0,1,0,1,0,1,1,0], [1,0,0,1,0,1,1,0,1,0], [1,1,0,1,0,0,1,0,1,0], [0,1,0,1,0,1,1,0,1,0], [1,1,1,0,0,1,0,0,1,0], [0,1,0,1,1,1,0,1,1,0], [1,1,0,1,0,1,0,1,0,0], [1,0,0,0,0,0,0,1,1,0], [1,1,0,1,1,1,1,0,1,0], [0,1,0,1,0,0,1,0,1,0], [0,1,0,1,0,1,1,0,1,0], [1,1,1,1,0,1,0,1,1,0], [0,1,0,0,1,1,0,1,1,0], [1,1,0,1,0,1,1,0,1,0], [1,0,0,1,0,0,1,0,0,0], [1,1,0,1,0,1,1,0,0,0], [0,1,1,1,0,1,0,0,0,0], [0,0,0,0,0,1,0,0,0,0] ]; max_len = len(maze[0]); core_diameter = 12.5; peg_diameter = 4; peg_length = 4; ring_thickness = 6.25; bolt_length = 2*len(maze)*peg_diameter; bolt_diameter = core_diameter + peg_length + (max_len*peg_diameter)/3.1415; bolt_diameter_capture = bolt_diameter * 1.25; bolt_capture_length = ring_thickness*1.25; path_width = peg_diameter; // the path 1/2 "width" bolt_radius_high = bolt_diameter/2; // the wall bolt_radius_low = bolt_radius_high - peg_length; // the path module ledge(radius=1, thickness=1, angle=45) { intersection() { intersection() { rotate([0,0,angle/2]) difference() { translate([0,0,thickness/2]) sphere(r=radius, center=true); union() { translate([-(radius/2),0,0]) cube([radius,3*radius,3*radius], center=true); rotate([0,0,180-angle]) translate([-(radius/2),0,0]) cube([radius,5*radius,5*radius], center=true); } } cube([5*radius,5*radius,thickness], center=true); } rotate([30,0,0]) cube([1.10*radius,3*radius,radius*0.85], center=true); } } module pie(radius=1, thickness=1, angle=45) { rotate([0,0,angle/2]) difference() { cylinder(r=radius, h=thickness, center=true); union() { translate([-(radius/2),0,0]) cube([radius,3*radius,3*radius], center=true); rotate([0,0,180-angle]) translate([-(radius/2),0,0]) cube([radius,3*radius,3*radius], center=true); } } } angle_1 = 360/max_len; angle_1_ch = bolt_radius_high * (angle_1 * 2 * 3.1415 / 360); angle_0 = angle_1; // Build up the maze with pie-slices for(i = [0:len(maze)]) { translate([0,0,bolt_length-(i*path_width*2)]) for(j = [0:len(maze[i])]) { rotate([0,0,j*360/(len(maze[i]))]) union() { if(maze[i][j] == 0) { pie(radius=bolt_radius_high, thickness=path_width*2, angle=angle_1*1.1); } else { if(maze[i-1][j] == 0) { union() { pie(radius=bolt_radius_low, thickness=path_width*2, angle=angle_0*1.1); translate([0,0,path_width/2]) ledge(radius=bolt_radius_high, thickness=path_width, angle=angle_0*1.1); } } else { pie(radius=bolt_radius_low, thickness=path_width*2, angle=angle_0*1.1); } } } } } union() { // Cap the ends... translate([0,0,bolt_length+1.5*bolt_capture_length]) union() { cylinder(r=bolt_diameter_capture/2, h=bolt_capture_length); spin(no=40,angle=360) translate([0,0,-bolt_capture_length/4]) ledge(radius=bolt_diameter_capture/2, thickness=bolt_capture_length, angle=45); } translate([0,0,-2*bolt_capture_length+path_width]) cylinder(r=bolt_diameter_capture/2, h=bolt_capture_length); translate([0,0,bolt_length]) cylinder(r=bolt_radius_low, h=bolt_capture_length); translate([0,0,-1*bolt_capture_length+path_width]) cylinder(r=bolt_radius_low, h=bolt_capture_length); // the ring! translate([0,0,-ring_thickness/2]) union() { difference() { cylinder(r=bolt_radius_high*1.5, h=ring_thickness); cylinder(r=bolt_radius_high+1, h=ring_thickness*10.55,center=true); } translate([-peg_length+bolt_radius_high*1.1,-peg_diameter/2,0]) cube([peg_length,peg_diameter,peg_diameter]); } }