diff options
Diffstat (limited to 'triumphboard')
| -rw-r--r-- | triumphboard/README.md | 38 | ||||
| -rw-r--r-- | triumphboard/triumph_board.scad | 142 |
2 files changed, 180 insertions, 0 deletions
diff --git a/triumphboard/README.md b/triumphboard/README.md new file mode 100644 index 0000000..afcd678 --- /dev/null +++ b/triumphboard/README.md @@ -0,0 +1,38 @@ +# TRIUMPH! magnetic gaming board + +[`triumph_board.scad`](triumph_board.scad) is a parameterized OpenSCAD model of a stackable, double-sided board for 15 mm TRIUMPH! armies. + +## Default dimensions + +| Feature | Dimension | +|---|---:| +| Exposed playing area | 960 × 640 mm | +| Finished outside size | 1020 × 700 mm | +| Wooden border width | 30 mm | +| Finished board depth | 30 mm | +| Steel core | 24 ga carbon steel, nominally 0.607 mm | +| Wood thickness per face | 14.6965 mm | +| Top corner holes | 10 × 10 mm, blind to the steel | + +The steel sheet is modeled at the full **1020 × 700 mm** outside size. The two wooden frames cover its 30 mm perimeter, leaving a **960 × 640 mm** exposed steel playing area on either face. This is the standard 24 × 16 base-width battlefield when 40 mm bases are used. + +The full-side short-end rails are 30 × 700 × 14.6965 mm. The long-edge rails fill between them and are 960 × 30 × 14.6965 mm. These dimensions describe each face; actual joinery, adhesives, edge treatment, and tolerances remain fabrication decisions. + +## Viewing and export + +Open the SCAD file and change `display` near the top: + +- `"assembled"` — complete board +- `"exploded"` — separates the layers for inspection +- `"steel"` — steel sheet only +- `"top_frame"` — drilled wooden face +- `"bottom_frame"` — undrilled wooden face +- `"short_end_piece"` or `"long_edge_piece"` — one representative rail + +All important measurements, including the hole size and inset, are parameters near the beginning of the file. + +## Construction assumption + +“3 cm deep” is interpreted as **30 mm of wood on each side of the sheet**. The steel is centered, giving equal wood thickness on both faces. + +The holes are square pockets subtracted through the top wood and stop at the sheet. They are intentionally absent from the opposite face; the future peg geometry is not included. diff --git a/triumphboard/triumph_board.scad b/triumphboard/triumph_board.scad new file mode 100644 index 0000000..11f5c5a --- /dev/null +++ b/triumphboard/triumph_board.scad @@ -0,0 +1,142 @@ +/* + Double-sided magnetic board for TRIUMPH! (15 mm figures) + + All dimensions are millimetres. The default exposed playing area is + 960 x 640 mm: 24 x 16 standard 40 mm TRIUMPH! base widths. + + Construction represented here: + - a 24 gauge cold-rolled carbon-steel core; + - 30 mm wide wooden frames on both faces; + - 30 mm total finished board depth, with the steel centred; + - 10 mm square blind corner holes in the top frame only; + - full-length short-end pieces, with long-edge pieces between them. + + The steel extends below the whole frame. This preserves a regulation-size + exposed playing area and gives the blind holes a metal stop. +*/ + +// ---------- User parameters ---------- + +playing_length = 960; // long dimension of exposed gaming area +playing_width = 640; // short dimension of exposed gaming area +frame_width = 30; // wooden border width in plan +steel_thickness = 0.607; // nominal 24 ga carbon steel (0.0239 in) +finished_depth = 60 + steel_thickness; // total board thickness, including steel + +peg_hole_size = 10; // square blind hole width +peg_hole_inset = 10; // from each outside edge to the hole edge + +// "assembled", "exploded", "steel", "top_frame", "bottom_frame", +// "short_end_piece", or "long_edge_piece" +display = "assembled"; +exploded_gap = 25; + +// Rendering colors only +wood_color = [0.58, 0.34, 0.16]; +steel_color = [0.50, 0.54, 0.58]; + +// ---------- Derived dimensions ---------- + +board_length = playing_length + 2 * frame_width; +board_width = playing_width + 2 * frame_width; +wood_face_depth = (finished_depth - steel_thickness) / 2; + +steel_bottom = -steel_thickness / 2; +steel_top = steel_thickness / 2; +bottom_wood_bottom = -finished_depth / 2; +top_wood_bottom = steel_top; + +epsilon = 0.02; + +assert(playing_length > 0 && playing_width > 0, + "The playing-area dimensions must be positive."); +assert(frame_width > 0 && finished_depth > steel_thickness, + "The frame must be wider than zero and deeper than the steel."); +assert(peg_hole_size > 0 && 2 * peg_hole_inset + peg_hole_size <= frame_width, + "Corner holes must fit completely inside the frame width."); + +// ---------- Components ---------- + +module steel_core(z = steel_bottom) { + color(steel_color) + translate([0, 0, z]) + cube([board_length, board_width, steel_thickness]); +} + +// Full-side pieces at the two short ends of the rectangular board. +module short_end_rails(height) { + cube([frame_width, board_width, height]); + translate([board_length - frame_width, 0, 0]) + cube([frame_width, board_width, height]); +} + +// Long-edge pieces occupy the remaining distance between the end pieces. +module long_edge_rails(height) { + translate([frame_width, 0, 0]) + cube([playing_length, frame_width, height]); + translate([frame_width, board_width - frame_width, 0]) + cube([playing_length, frame_width, height]); +} + +module wood_frame_blank(height) { + union() { + short_end_rails(height); + long_edge_rails(height); + } +} + +module corner_holes(height) { + hole_xy = [ + [peg_hole_inset, peg_hole_inset], + [board_length - peg_hole_inset - peg_hole_size, peg_hole_inset], + [peg_hole_inset, board_width - peg_hole_inset - peg_hole_size], + [board_length - peg_hole_inset - peg_hole_size, + board_width - peg_hole_inset - peg_hole_size] + ]; + + for (p = hole_xy) + translate([p[0], p[1], -epsilon]) + cube([peg_hole_size, peg_hole_size, height + 2 * epsilon]); +} + +module wood_frame(height, drilled = false) { + color(wood_color) + difference() { + wood_frame_blank(height); + if (drilled) + corner_holes(height); + } +} + +module assembled_board(explode = 0) { + // Sheet remains centred; the two frames move apart in exploded mode. + steel_core(); + + translate([0, 0, top_wood_bottom + explode]) + wood_frame(wood_face_depth, drilled = true); + + translate([0, 0, bottom_wood_bottom - explode]) + wood_frame(wood_face_depth, drilled = false); +} + +// ---------- Display / export selector ---------- + +if (display == "assembled") { + assembled_board(); +} else if (display == "exploded") { + assembled_board(exploded_gap); +} else if (display == "steel") { + translate([0, 0, -steel_bottom]) steel_core(); +} else if (display == "top_frame") { + wood_frame(wood_face_depth, drilled = true); +} else if (display == "bottom_frame") { + wood_frame(wood_face_depth, drilled = false); +} else if (display == "short_end_piece") { + // One representative full-side rail, placed at the origin for export. + color(wood_color) cube([frame_width, board_width, wood_face_depth]); +} else if (display == "long_edge_piece") { + // One representative infill rail, placed at the origin for export. + color(wood_color) cube([playing_length, frame_width, wood_face_depth]); +} else { + assert(false, str("Unknown display mode: ", display)); +} |
