fan-hinge.hs
I built this simple joint to attach a PC fan to a length of 2020 t-slot.
{- 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: 2020 t-slot Fan mount
--
-- description: I built this simple joint to attach a PC fan to a length of 2020 t-slot.
--
-- image: https://doscienceto.it/blog/photos/fan-hinge-01.jpg
-- image: https://doscienceto.it/blog/photos/fan-hinge-02.jpg
import qualified Waterfall
import Linear
import Data.Function ((&))
import Control.Lens ((^.))
= 20
baseDepth = 8
baseHeight = (hingeLength / 3) - 0.15
hingeSegLength = 20
hingeLength = 12
hingeDepth = 8
hingeBaseHeight = 12
baseSide = hingeLength + 2 * baseSide
baseLength = 16
fanDepth
hingeBase :: Waterfall.Solid
=
hingeBase let cond (a, b) | a ^. _xy == b ^. _xy = Just 5
| a ^. _z > 0 = Just 2
| otherwise = Nothing
= Waterfall.centeredCube &
b 0.5 * unit _z) &
Waterfall.translate (V3 baseDepth baseLength baseHeight) &
Waterfall.scale (
Waterfall.roundConditionalFillet cond= Waterfall.centeredCube &
slotGuide V3 6 baseLength 1)
Waterfall.scale (= mconcat [
baseHoles &
Waterfall.centeredCylinder V3 1.5 1.5 100) &
Waterfall.scale (<> (Waterfall.unitCylinder &
(V3 3 3 100) &
Waterfall.scale (^* (baseHeight -2) ))) &
Waterfall.translate (unit _z ^* (i * (hingeLength/2 + baseSide/2)))
Waterfall.translate (unit _y | i <- [-1, 1]
]=
hingeHalf &
(( Waterfall.centeredCube 0.5 * unit _z) &
Waterfall.translate (V3 hingeDepth hingeSegLength (hingeBaseHeight + baseHeight))
Waterfall.scale (<>
) &
( Waterfall.centeredCylinder V3 (hingeDepth/2) (hingeDepth/2) hingeSegLength) &
Waterfall.scale (pi/2) &
Waterfall.rotate (unit _x) (^* (hingeBaseHeight + baseHeight))
Waterfall.translate (unit _z `Waterfall.difference`
)) &
( Waterfall.centeredCylinder V3 1.5 1.5 100) &
Waterfall.scale (pi/2) &
Waterfall.rotate (unit _x) (^* (hingeBaseHeight + baseHeight))
Waterfall.translate (unit _z
)= mconcat [Waterfall.translate (unit _y ^* (i * hingeLength / 3 )) hingeHalf | i <- [-1, 1]]
hinge in (b {-- <> slotGuide --} <> hinge ) `Waterfall.difference` baseHoles
hingeTop :: Waterfall.Solid
=
hingeTop let
= 14
midH = 20
h =
p V2 0 hingeDepth /2)
Waterfall.pathFrom (V2 midH (hingeDepth/2)) (V2 midH (fanDepth/2)) (V2 h (fanDepth/2))
[ Waterfall.bezierTo (V2 h (negate fanDepth/2))
, Waterfall.lineTo (V2 midH (negate fanDepth/2)) (V2 midH (negate hingeDepth/2)) (V2 0 (negate hingeDepth/2))
, Waterfall.bezierTo (
]in Waterfall.translate (unit _z ^* (hingeBaseHeight + baseHeight)) $ Waterfall.rotate (unit _y) (negate pi/2) $
& Waterfall.closeLoop & Waterfall.fromPath
(( p & Waterfall.prism hingeSegLength
& Waterfall.translate (negate $ unit _z ^* hingeSegLength /2)
& Waterfall.rotate (unit _x) (pi/2)
<>
) &
( Waterfall.centeredCylinder V3 (hingeSegLength/2) (hingeSegLength/2) fanDepth) &
Waterfall.scale (pi/2) &
Waterfall.rotate (unit _z) (`Waterfall.difference` (Waterfall.centeredCube & Waterfall.translate (negate $ unit _x * 0.5) & Waterfall.uScale 100)) &
(^* h)
Waterfall.translate (unit _x <>
) &
( Waterfall.centeredCylinder V3 (hingeDepth/2) (hingeDepth/2) hingeSegLength) &
Waterfall.scale (pi/2)
Waterfall.rotate (unit _x) (`Waterfall.difference`
)) &
(( Waterfall.centeredCylinder V3 2 2 100) &
Waterfall.scale (pi/2) &
Waterfall.rotate (unit _z) (^* h)
Waterfall.translate (unit _x <>
) &
( Waterfall.centeredCylinder V3 1.5 1.5 100) &
Waterfall.scale (pi/2)
Waterfall.rotate (unit _x) (
))
main :: IO ()
= do
main 0.01 "hinge_combined.stl" (hingeBase <> hingeTop)
Waterfall.writeSolid 0.01 "hinge_base.stl" hingeBase
Waterfall.writeSolid 0.01 "hinge_top.stl" hingeTop Waterfall.writeSolid