Tape bobbin holes: rounded trapezoids, narrow side outward (v0.13.3)

Replace the inward-pointing triangular reel cutouts with rounded trapezoids —
wide toward the hub, narrow toward the rim. Generalize the corner-rounding helper
(roundedTri → roundedPoly) to handle the four-corner shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Reactorcoremeltdown
2026-07-20 15:54:14 +02:00
parent d43112f296
commit 5dfbda7c15
2 changed files with 19 additions and 14 deletions

View File

@@ -22,8 +22,8 @@ android {
// (android.media.midi) and AAudio low-latency audio we rely on. // (android.media.midi) and AAudio low-latency audio we rely on.
minSdk = 26 minSdk = 26
targetSdk = 34 targetSdk = 34
versionCode = 35 versionCode = 36
versionName = "0.13.2" versionName = "0.13.3"
// We provide our own instrumentation runner if/when tests are added. // We provide our own instrumentation runner if/when tests are added.
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -197,29 +197,34 @@ private fun DrawScope.drawReel(
) { ) {
val center = Offset(cx, cy) val center = Offset(cx, cy)
drawCircle(flange, radius = r, center = center) // metal flange drawCircle(flange, radius = r, center = center) // metal flange
for (k in 0 until 3) drawPath(bobbinHole(cx, cy, r, angle + k * 120f), hole) // triangular cutouts for (k in 0 until 3) drawPath(bobbinHole(cx, cy, r, angle + k * 120f), hole) // trapezoidal cutouts
drawCircle(hole, radius = r * 0.26f, center = center) // bobbin centre (open) drawCircle(hole, radius = r * 0.26f, center = center) // bobbin centre (open)
drawCircle(accent, radius = r * 0.26f, center = center, style = Stroke(width = 3f)) drawCircle(accent, radius = r * 0.26f, center = center, style = Stroke(width = 3f))
drawCircle(accent, radius = r * 0.14f, center = center, style = Stroke(width = 2f)) drawCircle(accent, radius = r * 0.14f, center = center, style = Stroke(width = 2f))
drawCircle(rim, radius = r, center = center, style = Stroke(width = 2.5f)) // flange edge drawCircle(rim, radius = r, center = center, style = Stroke(width = 2.5f)) // flange edge
} }
/** One inward-pointing rounded-triangular bobbin hole at [thetaDeg] around the reel. */ /** One rounded-trapezoidal bobbin hole at [thetaDeg] around the reel: wide toward the
* hub, narrow toward the rim (the narrow side faces outward). */
private fun bobbinHole(cx: Float, cy: Float, r: Float, thetaDeg: Float): Path { private fun bobbinHole(cx: Float, cy: Float, r: Float, thetaDeg: Float): Path {
val apex = polar(cx, cy, r * 0.36f, thetaDeg) // point toward the hub val rIn = r * 0.40f; val rOut = r * 0.86f
val baseL = polar(cx, cy, r * 0.82f, thetaDeg - 34f) // wide base toward the rim val inner = 44f // angular half-spread at the hub (wide side)
val baseR = polar(cx, cy, r * 0.82f, thetaDeg + 34f) val outer = 13f // angular half-spread at the rim (narrow side)
return roundedTri(apex, baseL, baseR, r * 0.10f) val innerL = polar(cx, cy, rIn, thetaDeg - inner)
val outerL = polar(cx, cy, rOut, thetaDeg - outer)
val outerR = polar(cx, cy, rOut, thetaDeg + outer)
val innerR = polar(cx, cy, rIn, thetaDeg + inner)
return roundedPoly(arrayOf(innerL, outerL, outerR, innerR), r * 0.09f)
} }
/** A triangle through [v0],[v1],[v2] with corners rounded to radius [corner]. */ /** A closed polygon through [v] with every corner rounded to radius [corner]. */
private fun roundedTri(v0: Offset, v1: Offset, v2: Offset, corner: Float): Path { private fun roundedPoly(v: Array<Offset>, corner: Float): Path {
val v = arrayOf(v0, v1, v2) val n = v.size
val path = Path() val path = Path()
for (i in 0 until 3) { for (i in 0 until n) {
val curr = v[i] val curr = v[i]
val prev = v[(i + 2) % 3] val prev = v[(i + n - 1) % n]
val next = v[(i + 1) % 3] val next = v[(i + 1) % n]
val a = curr + toward(curr, prev, corner) // approach point on the incoming edge val a = curr + toward(curr, prev, corner) // approach point on the incoming edge
val b = curr + toward(curr, next, corner) // leave point on the outgoing edge val b = curr + toward(curr, next, corner) // leave point on the outgoing edge
if (i == 0) path.moveTo(a.x, a.y) else path.lineTo(a.x, a.y) if (i == 0) path.moveTo(a.x, a.y) else path.lineTo(a.x, a.y)