Spinning Top
A disc-shaped spinning top in two parts: a body whose 45 degree conical underside runs down to the tip, and a stem with a knob that presses into a socket in the top of the body. The file computes the centre of mass of the assembled top from the volumes of its parts and checks that it stays below a chosen height relative to the disc radius, which is what makes a top spin steadily. The default body is 44 mm across and 27 mm tall, the stem 35 mm above it. Print the body upside down on its flat top face (the underside cone is a 45 degree overhang) and the stem standing beside it, as laid out; no supports. Adjustable parameters: disc radius and thickness, tip radius, stem length, radius and fit, and the balance limit.
# Spinning Top - a disc-shaped top with a pressed-in stem, balance checked from the centre of mass
#
# Two parts: the body (a disc with a 45 deg conical underside running down to the tip)
# and a stem that presses into a hole in the top of the body. The file computes the
# centre of mass of the assembled top from the volumes of its parts and checks that it
# sits low relative to the disc radius, which is what makes a top spin steadily.
# Print layout: body upside down on its flat top face (the underside cone is a 45 deg
# overhang), stem standing beside it. No supports.
@param 15..30 step:1 group:"Body" desc:"Disc radius (mm)"
$rd = 22
@param 4..10 step:0.5 group:"Body" desc:"Disc thickness at the rim (mm)"
$td = 6
@param 1..3 step:0.5 group:"Body" desc:"Tip radius (mm)"
$rt = 1.5
@param 25..50 step:1 group:"Stem" desc:"Stem length above the body (mm)"
$ls = 35
@param 2.5..4 step:0.25 group:"Stem" desc:"Stem radius (mm)"
$rs = 3
@param -0.1..0.2 step:0.05 group:"Stem" desc:"Hole clearance on the radius (mm); negative is a press fit"
$fit = 0.05
@param 0.6..1.2 step:0.05 group:"Balance" desc:"Highest allowed centre of mass above the tip, as a fraction of the disc radius (lower spins steadier)"
$max_com = 1.0
$hc = $rd - $rt # 45 deg cone from the rim down to the tip
$h_body = $hc + $td
$hole_d = $td + 4 # the stem socket reaches into the cone
$r_knob = $rs + 1.5
# --- Body: cone (tip at z = 0) + disc, socket from the top ---
$cone = cone $rt $rd $hc center:(true, true, false)
$disc = cylinder $rd $td center:(true, true, false) | translate 0 0 $hc | edges >Z | fillet 1.5
$body = ($cone + $disc) - (cylinder ($rs + $fit) ($hole_d + 1) center:(true, true, false) | translate 0 0 ($h_body - $hole_d))
# --- Stem: pin with a knob, printed standing ---
$stem = (cylinder $rs ($hole_d + $ls) center:(true, true, false) | faces <Z | chamfer 0.6)
+ (sphere $r_knob | translate 0 0 ($hole_d + $ls))
assert $body.solids == 1
assert $stem.solids == 1
# --- Centre of mass of the assembled top (tip at z = 0), from part volumes ---
$v_cone = pi * $hc / 3 * ($rt * $rt + $rt * $rd + $rd * $rd)
$z_cone = $hc * ($rt * $rt + 2 * $rt * $rd + 3 * $rd * $rd) / (4 * ($rt * $rt + $rt * $rd + $rd * $rd))
$v_disc = pi * $rd * $rd * $td
$z_disc = $hc + $td / 2
$v_stem = pi * $rs * $rs * $ls
$z_stem = $h_body + $ls / 2
$v_knob = 4 / 3 * pi * $r_knob ** 3
$z_knob = $h_body + $ls
$com = ($v_cone * $z_cone + $v_disc * $z_disc + $v_stem * $z_stem + $v_knob * $z_knob) / ($v_cone + $v_disc + $v_stem + $v_knob)
print "centre of mass height (mm)" $com
print "as a fraction of the disc radius" ($com / $rd)
assert $com / $rd <= $max_com
assert $body.volume ~ ($v_cone + $v_disc) tol:3% # the formulas describe the printed body
# --- Print layout ---
$body_p = $body | rotate 180 0 0 | floor
$stem_p = $stem | translate ($rd + $r_knob + 8) 0 0
assert $body_p.bbox.z ~ $h_body
$out = $body_p + $stem_p
assert $out.solids == 2
print "layout" $out.bbox
$out