summaryrefslogtreecommitdiff
path: root/triumphboard
diff options
context:
space:
mode:
Diffstat (limited to 'triumphboard')
-rw-r--r--triumphboard/README.md38
-rw-r--r--triumphboard/triumph_board.scad142
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));
+}