include ; include ; include ; module step(radius, angle, height, overhang = 2, underslope = 45) { step_depth = (PI * radius) * (angle / 360); echo("step_depth", step_depth); union() { difference() { linear_extrude(height=height * 2, center=true) { pie_slice(radius, 0, angle); } rotate([0,90,0]) translate([height,0,radius]) { rotate([0,0,0]) rotate([0,180,-underslope]) translate([0,0,0]) cube([step_depth * 4,step_depth * 4,radius], center=false); } } if (!draft) { translate([0,0,height - overhang / 2]) rotate([0,90,0]){ cylinder(r=overhang / 2, h=radius + 1, center=false, $fn=8); } } } } /* module step() { union() { linear_extrude(height=actual_step_height * 2, center=true) { pie_slice(radius + 1, 0, step_depth_deg); } rotate([0,90,0]) translate([step_height * 2,0,radius]) { rotate([0,0,0]) for (s = [0,10]) { translate([0,-step_depth * 2,s * 10]) cube([5,5,5], center=false); } } if (!draft) { translate([0,0,step_height - overhang / 2]) rotate([0,90,0]){ cylinder(r=overhang / 2, h=radius + 1, center=false, $fn=8); } } } } //*/ module stairs(radius, height, twists = 1, step_height = 1, step_depth = 1, overhang = 2, underslope = 45) { steps = floor((PI * radius * twists) / step_depth); step_depth_deg = (360 * twists) / steps; actual_step_height = height / floor(height / step_height); actual_step_depth = (step_depth_deg / 360) * (PI * radius * 2); floor_degree = atan2(actual_step_height, actual_step_depth); /* module step() { union() { linear_extrude(height=actual_step_height * 2, center=true) { pie_slice(radius + 1, 0, step_depth_deg); } rotate([0,90,0]) translate([step_height * 2,0,radius]) { rotate([0,0,0]) for (s = [0,10]) { translate([0,-step_depth * 2,s * 10]) cube([5,5,5], center=false); } } if (!draft) { translate([0,0,step_height - overhang / 2]) rotate([0,90,0]){ cylinder(r=overhang / 2, h=radius + 1, center=false, $fn=8); } } } } // */ module underside() { // linear_extrude( // height = height, // center = false, // twist = -twists * 360 - step_depth_deg, // $fn = 250 // ) { // pie_slice(radius * 2, 0, 90, $fn=16); // } } module all_steps() { for (s = [0:steps]) { translate([0, 0, s * actual_step_height]) { rotate([0, 0, step_depth_deg * s]) { step(radius, step_depth_deg, actual_step_height, 2, underslope); } } } } intersection() { cylinder(r=radius, h=height, center=false, $fn=256); difference() { all_steps(); if (!draft) { rotate([0,0,step_depth_deg / 2]) { underside(); } } } } } module banister() { // Banister intersection() { translate([-tower_radius, 0, 0]) rotate([0,0,exit]) scale([-1, 1, 1]) { difference() { cylinder(r=tower_radius + 2, h=tower_radius, center=false); translate([0,0,-1]) cylinder(r=tower_radius, h=tower_radius + 2, center=false); } } translate([0,0,-2]) cylinder(r=tower_radius - 2, h=tower_radius + 4, center=false); } } module bottom_stairs_and_banister() { difference() { union() { translate([-tower_radius, 0, 0]) rotate([0,0,exit]) scale([-1, 1, 1]) { difference() { stairs(tower_radius, bottom_stairs, twists=.14, step_height = 5.8, step_depth = 5); cylinder(r=5/2, h=bottom_stairs, center=false); } } } translate([0,0,bottom_stairs]) cylinder(r=tower_radius, h=tower_height, center=false); rotate([0,0,193]) translate([-10,0,0]) cube(size=[tower_radius + 10, tower_radius, bottom_stairs * 2], center=false); } difference() { union() { banister(); } rotate([0,0,180]) translate([-10,0,0]) cube(size=[tower_radius + 10, tower_radius, bottom_stairs * 2], center=false); } } module double_stairs() { intersection() { cylinder(r=tower_radius - brick_depth / 2, h=tower_height, center=false); union() { translate([0,0,bottom_stairs]) { stairs(tower_radius, tower_height - bottom_stairs, step_height = step_height, step_depth = step_depth, twists = twists, underslope = underslope); rotate([0,0,180]) stairs(tower_radius, tower_height - bottom_stairs, step_height = step_height, step_depth = step_depth, twists = twists, underslope = underslope); } } } } module floor() { cylinder(r=tower_radius, h=2, center=false); } module dungeon_bars() { max=8; module loop(n) { if (n >= 0) { rotate([0,0,n * -14.5]) translate([0, tower_radius - (2.5 * 1.5), 0]) scale([1,1.25,1]) { bonus=sin((n/max) * 180) * 18.5 + 4; cylinder(r=2.5, h=dungeon_height + bonus, center=false); } loop(n - 1); } } rotate([0,0,exit]) loop(max); } module front_door_neg() { scale([1,1,2]) rotate([90,0,exit]) cylinder(r=tower_radius / 2, h=100, center=false); } module front_door_rim() { // Front door rim intersection() { cylinder(r=tower_radius + 10, h=60, center=false); difference() { intersection() { scale([1,1,2]) rotate([90,0,exit]) cylinder(r=tower_radius / 2 + 5, h=90, center=false); cylinder(r=tower_radius + 10, h=tower_height, center=false); } // Front door scale([1,1,2]) rotate([90,0,exit]) cylinder(r=tower_radius / 2, h=100, center=false); // Inner tower cylinder(r=tower_radius - groove, h=tower_height, center=true); } } } module dungeon_window_neg() { rotate([90,0,0]) translate([0,0,tower_radius]) cylinder(r=tower_radius, h=42, center=true); } module dungeon_window_rim() { intersection() { //cyl(tower_radius + 10, 50, center=false); union() { intersection() { cylinder(r=tower_radius + 10, h=100, center=true); linear_extrude(height=tower_height, center=false, convexity=10, twist=0) { pie_slice(tower_radius + 10, 180 + 90 - 59.5, 180 + 90 + 59.5); } difference() { rotate([90,0,0]) translate([0,0,tower_radius]) cylinder(r=tower_radius + 5, h=42, center=true); scale([1,0.9,1]) dungeon_window_neg(); } } intersection() { linear_extrude(height=50, center=false) { pie_slice(tower_radius + 10, 180 + 90 - 59.5, 180 + 90 - 59.5 + 360 * (3 / (tower_radius * PI))); pie_slice(tower_radius + 10, 180 + 90 + 59.5, 180 + 90 + 59.5 - 360 * (3 / (tower_radius * PI))); } rotate([90,0,0]) translate([0,0,tower_radius]) cylinder(r=tower_radius + 5, h=42, center=true); } } } } //* union() { floor(); double_stairs(); difference() { tower(tower_radius, tower_height); front_door_neg(); dungeon_window_neg(); } intersection() { tower(tower_radius + 5, 60); union() { front_door_rim(); dungeon_window_rim(); } } dungeon_bars(); bottom_stairs_and_banister(); cylinder(r=pin_diameter / 2, h=tower_height + pin_height, center=false); }