Alan Colon 7 years ago
commit
a71d387942
4 changed files with 357 additions and 0 deletions
  1. 251 0
      DiceTower.scad
  2. 21 0
      config.scad
  3. 25 0
      pie_slice.scad
  4. 60 0
      tower.scad

+ 251 - 0
DiceTower.scad

@@ -0,0 +1,251 @@
+include <config.scad>;
+include <pie_slice.scad>;
+include <tower.scad>;
+
+  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);
+}

+ 21 - 0
config.scad

@@ -0,0 +1,21 @@
+draft=false;
+
+tower_radius = 85 / 2;
+tower_height = 135;
+groove = 1;
+target_brick_width = 10;
+target_brick_height = 5;
+brick_depth = 7;
+bottom_offset = 18.65;
+dungeon_height = tower_radius - bottom_offset;
+bottom_stairs = tower_radius - bottom_offset;
+exit = -121.5;
+step_height=5;
+step_depth=6.7; // 5;
+twists = 2;
+underslope=68; //62.5;
+pin_diameter=6;
+pin_height=10;
+outer_pin_distance=37.2;
+outer_pin_diameter=4;
+outer_pin_angle=180;

+ 25 - 0
pie_slice.scad

@@ -0,0 +1,25 @@
+module pie_slice(radius, start_angle, end_angle) {
+    R = radius * sqrt(2) + 1;
+    a0 = (4 * start_angle + 0 * end_angle) / 4;
+    a1 = (3 * start_angle + 1 * end_angle) / 4;
+    a2 = (2 * start_angle + 2 * end_angle) / 4;
+    a3 = (1 * start_angle + 3 * end_angle) / 4;
+    a4 = (0 * start_angle + 4 * end_angle) / 4;
+    m = 2;
+    if(end_angle > start_angle) {
+      intersection() {
+        circle(r=radius);
+        polygon([
+            [0,0],
+            [R * m * cos(a0), R * m * sin(a0)],
+            [R * m * cos(a1), R * m * sin(a1)],
+            [R * m * cos(a2), R * m * sin(a2)],
+            [R * m * cos(a3), R * m * sin(a3)],
+            [R * m * cos(a4), R * m * sin(a4)],
+            [0,0]
+        ]);
+      }
+    } else {
+      pie_slice(radius, end_angle, start_angle);
+    }
+}

+ 60 - 0
tower.scad

@@ -0,0 +1,60 @@
+module tower(radius, height) {
+  // groove = .75;
+  // target_brick_width = 10;
+  // target_brick_height = 5;
+  // brick_depth = 5;
+  circum = 2 * radius * PI;
+  bricks = floor(circum / target_brick_width);
+  brick_width_deg = 360 / bricks;
+  rings = floor(height / target_brick_height);
+  brick_height = height / rings;
+  $fn = bricks;
+
+  module ring(n) {
+    start_deg = 0;
+    end_deg = brick_width_deg;
+    translate([0, 0, -1]) {
+      if (n > 1) {
+        // Left groove
+        for (i=[0:bricks]) {
+          translate([radius * cos(brick_width_deg * i), radius * sin(brick_width_deg * i), 1]) {
+            rotate([0, 0, 45 + brick_width_deg * i]) {        
+              cube(size=[groove, groove, brick_height], center=false);
+            }
+          }
+        }
+      }
+      
+    }
+    // Bottom groove
+    rotate_extrude() {
+      translate([radius * cos(start_deg), radius * sin(start_deg)]) {
+        rotate([0, 0, 45]) {
+          square(size=[groove, groove], center=true); 
+        }
+      }
+    }
+  }
+
+  module loop(n) {
+    if (n > 0) {
+      union(){
+        ring(n);
+        rotate([0,0,brick_width_deg / 2]) {
+          translate([0,0,brick_height]) {
+            loop(n - 1);
+          }
+        }
+      }
+    }
+  }
+  difference() {
+    cylinder(r=radius, h=height, center=false);
+    translate([0,0,-1]) {
+      cylinder(r=radius - brick_depth, h=height + 2, center=false);
+    }
+    if (!draft) {
+      loop(rings + 1);
+    }
+  }
+}