knob.hs
A pal of mine DJs under the name Syntax Terror.
A while back, he contacted me about printing some replacement dials for his Traktor Kontrol X1 MK2, as these had apparently fallen off during transit.
He sent me a list of possible knob designs from Thingiverse.
Now, I’m broadly of the opinion that the point of having a 3d printer is that you can make custom parts. Thingiverse is great, but if you’re just going to print stuff from Thingiverse all the time, you’d be better off with an Alibaba account.
With this in mind, I thought I’d have a go at designing some custom knobs, instead.
This meant I was able to use the line “I’ve got some knobs here with your name on them”, while we were arranging postage.
While I’m relatively happy with how these came out, I regret not playing around with the bevel radius and number of cuts a little more than I did.
#!/usr/bin/env stack
{- stack script --resolver lts-22.6
--package linear
--package waterfall-cad
--extra-dep waterfall-cad-0.4.0.0
--extra-dep opencascade-hs-0.4.0.0
-}
-- short-description: Tommy's Knobs
-- description: [A pal of mine](https://www.tommyp.org/) DJs under the name [Syntax Terror](https://soundcloud.com/syntax-terrorist).
-- description:
-- description: A while back, he contacted me about printing some replacement dials for his [Traktor Kontrol X1 MK2](https://www.native-instruments.com/en/products/traktor/dj-controllers/traktor-x1/), as these had apparently fallen off during transit.
-- description:
-- description: He sent me a list of possible knob designs from Thingiverse.
-- description:
-- description: Now, I'm broadly of the opinion that the point of having a 3d printer is that you can make _custom parts_.
-- description: Thingiverse is great, but if you're just going to print stuff from Thingiverse all the time, you'd be better off with an Alibaba account.
-- description:
-- description: With this in mind, I thought I'd have a go at designing some custom knobs, instead.
-- description:
-- description: This meant I was able to use the line "I've got some knobs here with your name on them", while we were arranging postage.
-- description:
-- description: While I'm relatively happy with how these came out, I regret not playing around with the bevel radius and number of cuts a little more than I did.
-- image: https://doscienceto.it/blog/photos/knobs-01.jpg
-- image: https://doscienceto.it/blog/photos/traktor_kontrol.jpg
import qualified Waterfall
import Linear
shaft :: Waterfall.Solid
=
shaft let r = 3
= 20
h = 2
cutOff in (Waterfall.scale (V3 r r h) Waterfall.unitCylinder) `Waterfall.difference`
*^ unit _y) $ Waterfall.scale (V3 h h (h*3)) $ Waterfall.translate (0.5 *^ unit _y) $ Waterfall.centeredCube)
(Waterfall.translate (cutOff
knob :: Waterfall.Shape -> Waterfall.Solid
=
knob t let rInner = 19/2
= 19
h = Waterfall.roundConditionalFillet (\(V3 _ _ z, V3 _ _ z') -> if z > h/2 && z' > h/2 then Just 5 else Nothing)
fillet = 1.75
cutR = 8
cutN = Waterfall.rotate (unit _z) (pi/cutN) $ mconcat $ take 10 $ iterate (Waterfall.rotate (unit _z) (2*pi/cutN)) $ Waterfall.translate (rInner *^ unit _y) $ Waterfall.scale (V3 cutR cutR (h*3)) $ Waterfall.centeredCylinder
cuts = fillet $ Waterfall.scale (V3 rInner rInner h) $ Waterfall.unitCylinder
plainCyl = 21/2
rOuter = 2
baseH = rOuter + baseH
coneS = 0.75
coneGrad = Waterfall.scale (V3 coneS coneS (coneS * coneGrad)) $ Waterfall.translate (unit _z) $ Waterfall.rotate (unit _x) pi $ Waterfall.unitCone
baseCone = (Waterfall.scale (V3 rOuter rOuter (h/2)) Waterfall.unitCylinder) `Waterfall.intersection` baseCone
base = Waterfall.translate ((h - 20 - 2) *^ unit _z) $ shaft
shaft'
= 0.5
tDepth = Waterfall.translate ((h- tDepth*9) *^ unit _z) $ Waterfall.prism (tDepth *10) t
text in (((plainCyl `Waterfall.difference` cuts) `Waterfall.union` base) `Waterfall.difference` shaft') `Waterfall.union` text
main :: IO ()
= do
main let stlRes = 0.05
<- Waterfall.fontFromSystem "monospace" Waterfall.Regular 5
font "knob-syntax.stl" (knob $ Waterfall.text font "syntax")
Waterfall.writeSTL stlRes "knob-terror.stl" (knob $ Waterfall.text font "terror") Waterfall.writeSTL stlRes