Chess Set
A Staunton-style chess set in six pieces, each a revolved profile computed from one parameter, the king height (95 mm by default, 60 to 120). The queen, bishop, knight, rook and pawn are the usual fractions of the king, the base radius follows the height, and the heads are built on 45 deg cones so nothing overhangs: ball and cross, notched crown, slit mitre, an extruded horse-head silhouette, a castle top with crenellations, and a plain ball. The set view is 228 x 38 x 95 mm; pick a single piece to print it on its own (you need eight pawns, two each of the others, and a king and queen per side). Print standing, no supports. A 1 mm recess under each base takes a felt pad and can be switched off.
# Chess Set - six Staunton-style pieces, every profile computed from the king height
#
# Each piece is a profile of (radius, height) revolved around Z: a chamfered base,
# a concave flare, a tapered stem and a 45 deg collar, then a head that differs per
# piece (ball and cross, crown, mitre, horse-head silhouette, castle, ball). The
# piece heights are the usual fractions of the king (queen 0.9, bishop 0.75, knight
# 0.65, rook 0.6, pawn 0.5) and every base radius follows from the height, so one
# parameter resizes the whole set. Every outward slope is 45 deg or less and the
# balls sit on 45 deg cones, so the pieces print standing with no supports. A 1 mm
# recess under each base takes a felt pad. Print the set with `piece = "set"` or
# one piece at a time (eight pawns are needed per side).
@param 60..120 step:5 group:"Size" desc:"Height of the king (mm)"
$king_h = 95
@param choices:["set", "king", "queen", "bishop", "knight", "rook", "pawn"] group:"Output" desc:"Which piece to build"
$piece = "set"
@param group:"Details" desc:"Shallow recess under the base for a felt pad"
$felt = true
$K = $king_h
$c45 = sqrt(2) / 2
# --- heights as fractions of the king ---------------------------------
$h_king = $K
$h_queen = 0.9 * $K
$h_bishop = 0.75 * $K
$h_knight = 0.65 * $K
$h_rook = 0.6 * $K
$h_pawn = 0.5 * $K
# base radius from the piece height (king 0.2 K, pawn 0.15 K)
def rbase($h) = 0.1 * $K + 0.1 * $h
# --- trunk: base, flare, stem and collar, revolved. $hb = height of the collar top,
# --- $rn = radius of the flat top the head sits on
def trunk($hb, $rb, $rn) = workplane XZ
| sketch [(0, 0), ($rb - 1.5, 0), ($rb, 1.5), ($rb, 0.08 * $hb),
arc ($rb, 0.08 * $hb) (0.615 * $rb, 0.199 * $hb) (0.45 * $rb, 0.42 * $hb),
(0.38 * $rb, 0.72 * $hb),
(0.75 * $rb, 0.72 * $hb + 0.37 * $rb),
(0.75 * $rb, $hb - 4),
($rn, $hb), (0, $hb)]
| revolve Z
# --- ball head on a 45 deg cone: cone from radius $rn at z0 up to the sphere's
# --- 45 deg tangent point, then a 3-point arc over the top. Returns the solid.
def ball_zc($z0, $rn, $r) = $z0 + 2 * $r * $c45 - $rn
def ball($z0, $rn, $r) = workplane XZ
| sketch [(0, $z0 - 1), ($rn, $z0 - 1), ($rn, $z0),
($r * $c45, ball_zc($z0, $rn, $r) - $r * $c45),
arc ($r * $c45, ball_zc($z0, $rn, $r) - $r * $c45) ($r, ball_zc($z0, $rn, $r)) (0, ball_zc($z0, $rn, $r) + $r)]
| revolve Z
def ball_top($z0, $rn, $r) = ball_zc($z0, $rn, $r) + $r
def felt_cut($rb) = cylinder ($rb - 2.5) 2 | translate 0 0 0
def with_felt($p, $rb) = if $felt then ($p - felt_cut($rb)) else $p
# --- King: ball with a cross on top ------------------------------------
$rb_k = rbase($h_king)
$hb_k = 0.72 * $K
$rn_k = 5
$r_k = 0.08 * $K
$top_k = ball_top($hb_k, $rn_k, $r_k)
$cross_h = $h_king - $top_k
assert $cross_h > 0.08 * $K
$cross = (box (0.04 * $K) (0.025 * $K) ($cross_h + 2) center:(true, true, false) | translate 0 0 ($top_k - 2))
+ (box (0.11 * $K) (0.025 * $K) (0.03 * $K) center:(true, true, false) | translate 0 0 ($top_k + $cross_h * 0.55 - 0.015 * $K))
$king0 = trunk($hb_k, $rb_k, $rn_k) + ball($hb_k, $rn_k, $r_k) + $cross
$king = with_felt($king0, $rb_k)
# --- Queen: larger ball with eight notches (the crown) and a finial ball --------
$rb_q = rbase($h_queen)
$hb_q = 0.66 * $K
$rn_q = 5
$r_q = 0.095 * $K
$top_q = ball_top($hb_q, $rn_q, $r_q)
$zc_q = ball_zc($hb_q, $rn_q, $r_q)
$notch = sphere (0.28 * $r_q) | translate ($r_q + 0.05 * $r_q) 0 ($zc_q + 0.45 * $r_q) | polar 8 0
$rf_q = 0.035 * $K
assert $h_queen - $rf_q > $top_q
$finial_q = sphere $rf_q | translate 0 0 ($h_queen - $rf_q)
$neck_q = cylinder (0.6 * $rf_q) ($h_queen - $rf_q - $top_q + 2) | floor | translate 0 0 ($top_q - 1)
$queen0 = (trunk($hb_q, $rb_q, $rn_q) + ball($hb_q, $rn_q, $r_q) + $neck_q + $finial_q) - $notch
$queen = with_felt($queen0, $rb_q)
# --- Bishop: pointed mitre with a slit, finial ball --------------------------
$rb_b = rbase($h_bishop)
$hb_b = 0.5 * $K
$rn_b = 5
$r_b = 0.085 * $K
$zc_b = ball_zc($hb_b, $rn_b, $r_b)
$mitre_top = $zc_b + 1.5 * $r_b
$mitre = workplane XZ
| sketch [(0, $hb_b - 1), ($rn_b, $hb_b - 1), ($rn_b, $hb_b),
($r_b * $c45, $zc_b - $r_b * $c45),
arc ($r_b * $c45, $zc_b - $r_b * $c45) ($r_b, $zc_b) (0, $mitre_top)]
| revolve Z
$slit = box (2 * $r_b + 2) 1.2 (2 * $r_b) | rotate 0 -40 0 | translate (0.9 * $r_b) 0 ($zc_b + 0.6 * $r_b)
$rf_b = 0.03 * $K
assert $h_bishop - $rf_b > $mitre_top
$finial_b = sphere $rf_b | translate 0 0 ($h_bishop - $rf_b)
$neck_b = cylinder (0.55 * $rf_b) ($h_bishop - $rf_b - $mitre_top + 3) | floor | translate 0 0 ($mitre_top - 2)
$bishop0 = (trunk($hb_b, $rb_b, $rn_b) + $mitre + $neck_b + $finial_b) - $slit
$bishop = with_felt($bishop0, $rb_b)
# --- Knight: horse-head silhouette extruded across the trunk top ------------
$rb_n = rbase($h_knight)
$hb_n = 0.33 * $K
$rn_n = 0.6 * $rb_n
$head_h = $h_knight - $hb_n
$u = $head_h / 30 # silhouette drawn 30 units tall, +X is forward
$head_t = 0.8 * $rb_n
$head = workplane XZ
| polyline [(-7 * $u, -1), (8 * $u, -1), (8 * $u, 4 * $u), (14 * $u, 10 * $u), (15 * $u, 15 * $u),
(12 * $u, 17 * $u), (10 * $u, 18 * $u), (8 * $u, 24 * $u), (9 * $u, 30 * $u),
(6 * $u, 27 * $u), (3 * $u, 29.5 * $u), (0, 26 * $u), (-6 * $u, 18 * $u), (-7 * $u, 8 * $u)]
| extrude $head_t
| translate 0 ($head_t / 2) $hb_n
$eye = sphere (1.2 * $u) | translate (9.5 * $u) ($head_t / 2) ($hb_n + 21 * $u)
$knight0 = (trunk($hb_n, $rb_n, $rn_n) + $head) - $eye - ($eye | mirror "Y")
$knight = with_felt($knight0, $rb_n)
# --- Rook: castle top with four crenellations and a recessed top --------------
$rb_r = rbase($h_rook)
$hb_r = 0.45 * $K
$rn_r = 0.55 * $rb_r
$rt = 0.72 * $rb_r
$tower = workplane XZ
| sketch [(0, $hb_r - 1), ($rn_r, $hb_r - 1), ($rn_r, $hb_r), ($rt, $hb_r + ($rt - $rn_r)), ($rt, $h_rook), (0, $h_rook)]
| revolve Z
$cren_d = 0.045 * $K
$cren = box (2 * $rt + 2) (0.3 * $rt) ($cren_d + 1) center:(true, true, false) | translate 0 0 ($h_rook - $cren_d)
$recess = cylinder ($rt - 2.2) ($cren_d + 1) | floor | translate 0 0 ($h_rook - $cren_d)
$rook0 = (trunk($hb_r, $rb_r, $rn_r) + $tower) - $recess - $cren - ($cren | rotate 0 0 90)
$rook = with_felt($rook0, $rb_r)
# --- Pawn: ball sized so the top lands exactly on the pawn height -------------
$rb_p = rbase($h_pawn)
$hb_p = 0.36 * $K
$rn_p = 4
$r_p = ($h_pawn - $hb_p + $rn_p) / (1 + 2 * $c45)
$pawn0 = trunk($hb_p, $rb_p, $rn_p) + ball($hb_p, $rn_p, $r_p)
$pawn = with_felt($pawn0, $rb_p)
# --- checks ----------------------------------------------------------------
assert $king.solids == 1
assert $queen.solids == 1
assert $bishop.solids == 1
assert $knight.solids == 1
assert $rook.solids == 1
assert $pawn.solids == 1
assert $king.bbox.z ~ $h_king
assert $queen.bbox.z ~ $h_queen
assert $bishop.bbox.z ~ $h_bishop
assert $knight.bbox.z ~ $h_knight
assert $rook.bbox.z ~ $h_rook
assert $pawn.bbox.z ~ $h_pawn
assert $king.bbox.x ~ (2 * $rb_k)
assert $pawn.bbox.x ~ (2 * $rb_p)
assert $king.bbox.min[2] ~ 0 tol:0.01
print "king base dia" (2 * $rb_k)
print "pawn ball dia" (2 * $r_p)
# --- layout: the six pieces in a row along X, 6 mm apart -----------------------
$gap = 6
$x_q = $rb_k + $gap + $rb_q
$x_b = $x_q + $rb_q + $gap + $rb_b
$x_n = $x_b + $rb_b + $gap + $rb_n
$x_r = $x_n + $rb_n + $gap + $rb_r
$x_p = $x_r + $rb_r + $gap + $rb_p
$set = union [$king,
$queen | translate $x_q 0 0,
$bishop | translate $x_b 0 0,
$knight | translate $x_n 0 0,
$rook | translate $x_r 0 0,
$pawn | translate $x_p 0 0]
assert $set.solids == 6
assert $set.bbox.x ~ ($x_p + $rb_p + $rb_k)
if $piece == "king" then $king
else if $piece == "queen" then $queen
else if $piece == "bishop" then $bishop
else if $piece == "knight" then $knight
else if $piece == "rook" then $rook
else if $piece == "pawn" then $pawn
else $set