tslot-endcap.hs

I’ve got a bunch of 2020 t-slot bolted to the back of my monitors, which I use to mount stuff to.

I wanted a way to terminate these, while also giving me a place to hang stuff off it, so I designed this hook.

I printed it in two halves, to avoid printing overhangs. The nice thing about printing split parts to fit on t-slot, was that I found fitting each half to the t-slot before gluing them worked really well to align them.

tslot-endcap-hook.stl

tslot-endcap-hook-half-A.stl

tslot-endcap-hook-half-B.stl

raw haskell source

#!/usr/bin/env stack
{- stack script --resolver lts-21.13 
    --package linear
    --package lens
    --package waterfall-cad
    --extra-dep waterfall-cad-0.4.0.0
    --extra-dep opencascade-hs-0.4.0.0
-}
-- short-description:  Hook Endcap for 2020 t-slot 
-- description: 
-- description: I’ve got a bunch of 2020 t-slot bolted to the back of my monitors, which I use to mount stuff to.
-- description: 
-- description: I wanted a way to terminate these, while also giving me a place to hang stuff off it, so I designed this hook.
-- description: 
-- description: I printed it in two halves, to avoid printing overhangs.
-- description: The nice thing about printing split parts to fit on t-slot,
-- description: was that I found fitting each half to the t-slot before gluing them worked really well to align them.

import qualified Waterfall 
import qualified Waterfall.TwoD.Shape as Shape
import Waterfall.Internal.Solid (debug)
import Linear 
import Control.Lens ((^.))

hook :: Waterfall.Solid
hook = let r1 = 20 :: Double
           r2 = 8 :: Double 
           end = let x = r1 *^ unit _z in x + Waterfall.rotate (unit _x) (pi/4) x
           p = Waterfall.arcVia (zero :: V3 Double) (2 * r1 *^ unit _z) end
           face = Waterfall.uScale2D r2 $ Waterfall.unitCircle
           sphere = Waterfall.uScale r2 Waterfall.unitSphere
        in Waterfall.sweep p face `Waterfall.union` (Waterfall.translate end sphere) `Waterfall.union` sphere

-- 2020 t-slot
tSlotHole :: Waterfall.Solid
tSlotHole = 
  let holeHeight = 20
      mainHole = Waterfall.scale (V3 20 20 (holeHeight*1.1)) Waterfall.centeredCube
      oneSlot = 
        Waterfall.translate (10 * unit _y) .
          Waterfall.scale (V3 6 12 (holeHeight * 6)) $ 
            Waterfall.centeredCube
      allSlots = mconcat . take 4 . iterate (Waterfall.rotate (unit _z) (pi/2)) $ oneSlot 
   in Waterfall.offset 0.25 1e-5 (mainHole `Waterfall.difference` allSlots)

tslotEndcapHook :: Waterfall.Solid
tslotEndcapHook = 
  let block = 
          Waterfall.roundFillet 2 .
            Waterfall.translate (5 * unit _z) . 
              Waterfall.scale (V3 25 25 20) $ 
                Waterfall.centeredCube
      positionedHook = Waterfall.translate (12 *^ unit _z) hook
   in (block `Waterfall.union` positionedHook) `Waterfall.difference` tSlotHole

halfBlock = Waterfall.uScale 200 $ Waterfall.translate (0.5 *^ unit _x) Waterfall.centeredCube

main :: IO ()
main = do
    let stlRes = 0.1
    Waterfall.writeSTL stlRes "tslot-endcap-hook.stl" tslotEndcapHook
    Waterfall.writeSTL stlRes "tslot-endcap-hook-half-A.stl" $ tslotEndcapHook `Waterfall.difference` halfBlock
    Waterfall.writeSTL stlRes "tslot-endcap-hook-half-B.stl" $ tslotEndcapHook `Waterfall.intersection` halfBlock