Angle Gauge
A protractor with a pivoting pointer arm. The semicircular plate carries a degree scale with 1 degree ticks and numbers every 10 degrees, generated from the code, and the arm pivots at the centre on a printed split snap pin that holds it by friction at any angle. Lay the straight edge along the edge of a board, swing the arm to a line or a second edge and read the angle where the arm's centre line crosses the scale, or set the arm to an angle and scribe along it. The straight edge is offset below the pivot and the baseline through the pivot is engraved. The default 60 mm radius lays out as 126 x 107 x 10 mm. Three parts, all printed flat with no supports: the plate, the arm and the pin standing on its head. Parameters: scale radius, plate thickness, arm width and tick spacing.
# Angle Gauge - protractor with a pivoting pointer arm on a printed snap pin
#
# A semicircular protractor plate with a degree scale (1 deg ticks, numbers every 10) and a
# pointer arm that pivots at the centre on a split snap pin, so the arm holds the angle it is
# set to by friction. Lay the straight edge along the edge of a board, swing the arm to the
# line or the second edge and read the angle where the arm's centre line crosses the scale;
# or set the arm to an angle and scribe along it. The straight edge is offset below the
# pivot and the baseline through the pivot is engraved.
# Three parts, all printed flat with no supports: plate, arm and the pin standing on its head.
@param 40..100 desc:"Scale radius (mm)"
$radius = 60
@param 2..4 step:0.5 desc:"Plate thickness (mm)"
$t = 3
@param 10..16 desc:"Arm width (mm)"
$arm_w = 12
@param 1..5 desc:"Tick spacing (deg)"
$tick_deg = 1
# --- Plate: a semicircle above the baseline plus a strip below it ----------------------
$strip = 8
$disc = circle $radius | extrude $t
$lower = box (2 * $radius + 2) ($radius + 2) ($t + 2) center:(true, false, false) | translate 0 (-$radius - 2 - $strip) -1
$half = $disc - $lower # keeps y >= -strip
$base = box (2 * $radius) $strip $t center:(true, false, false) | translate 0 (-$strip) 0
$plate0 = $half + $base
# scale: ticks from the rim inward, every tick_deg, longer at 5 and 10
$n_tick = floor(180 / $tick_deg) + 1
def ang($i) = $i * $tick_deg
def tl($i) = if ang($i) % 10 == 0 then 7 else if ang($i) % 5 == 0 then 5 else 3
$tick = box 5 0.35 1 center:(false, true, false) # along +X from the origin, rotated into place
$ticks = union [box tl($i) 0.35 1 center:(false, true, false) | translate ($radius - 1 - tl($i)) 0 ($t - 0.4) | rotate 0 0 ang($i) for $i in range($n_tick)]
$nums = union [text ("" + ($k * 10)) 3.2 | rotate ($k * 10 - 90) | extrude 1 | translate (($radius - 12) * cos($k * 10)) (($radius - 12) * sin($k * 10)) ($t - 0.4) for $k in range(19)]
# baseline through the pivot and a centre mark
$baseline = box (2 * $radius) 0.4 1 center:(true, true, false) | translate 0 0 ($t - 0.4)
$pin_d = 6
$pin_fit = 0.25
$hole = cylinder ($pin_d / 2 + $pin_fit) ($t + 2) center:(true, true, false) | translate 0 0 -1
$plate1 = $plate0 - $ticks
$plate2 = $plate1 - $nums
$plate3 = $plate2 - $baseline
$plate = $plate3 - $hole
assert $plate.solids == 1
# --- Arm: pivot end round, pointed tip past the scale, centre line engraved -------------
$arm_l = $radius + 10
$arm_shape = polyline [(0, -($arm_w / 2)), ($arm_l - 8, -($arm_w / 2)), ($arm_l, 0), ($arm_l - 8, $arm_w / 2), (0, $arm_w / 2)]
$arm0 = union [circle ($arm_w / 2), $arm_shape] | extrude $t
$line = box ($arm_l - 8) 0.4 1 center:(false, true, false) | translate 4 0 ($t - 0.4)
$arm1 = $arm0 - $line
$arm = $arm1 - $hole
assert $arm.solids == 1
# --- Snap pin: head, shaft through both parts, barb at the end, slotted to compress -------
$shaft_l = 2 * $t + 0.4
$head = cylinder 5 2 center:(true, true, false)
$shaft = cylinder ($pin_d / 2) $shaft_l center:(true, true, false) | translate 0 0 2
$barb = cone ($pin_d / 2 + 0.5) ($pin_d / 2 - 0.6) 1.6 center:(true, true, false) | translate 0 0 (2 + $shaft_l)
$pin0 = union [$head, $shaft, $barb]
$slot = box 1.2 ($pin_d + 4) ($shaft_l + 1.6 + 1) center:(true, true, false) | translate 0 0 (2 + 1.5)
$pin = $pin0 - $slot
assert $pin.solids == 1
# --- Print layout -----------------------------------------------------------------------
$arm_p = $arm | translate (-$radius) (-$strip - $arm_w / 2 - 8) 0
$pin_p = $pin | translate ($radius - 8) (-$strip - $arm_w - 22) 0
$out = union [$plate, $arm_p, $pin_p]
assert $out.solids == 3
assert clear($plate, $arm_p)
assert clear($arm_p, $pin_p)
assert $plate.bbox.x ~ (2 * $radius)
assert $plate.bbox.y ~ ($radius + $strip)
print "ticks" $n_tick
$out