Skip to content

Instantly share code, notes, and snippets.

@joe-warren
Created January 30, 2024 03:08
Show Gist options
  • Save joe-warren/522497303684a820eb05473e15eab3db to your computer and use it in GitHub Desktop.
Save joe-warren/522497303684a820eb05473e15eab3db to your computer and use it in GitHub Desktop.
import qualified Waterfall
import qualified Waterfall.TwoD.Shape as Shape
import Waterfall.Internal.Solid (debug)
import Linear
import Control.Lens ((^.))
pathFactor :: Double
pathFactor = 12.5
heartPath :: Waterfall.Path
heartPath =
Waterfall.uScale pathFactor $ Waterfall.pathFrom (V3 5 0 5)
[ Waterfall.arcViaRelative (V3 3 0 (-3)) (V3 0 0 (-6))
, Waterfall.bezierTo (V3 3 0 (-1)) (V3 2.5 0 (-0.75)) zero
]
heartPath2D :: Waterfall.Path2D
heartPath2D =
Waterfall.uScale2D pathFactor $ Waterfall.pathFrom zero
[ Waterfall.bezierTo (V2 (-0.75) 2.5) (V2 (-1) 3) (V2 (-1) 5)
, Waterfall.arcViaRelative (V2 3 3) (V2 6 0)
, Waterfall.arcViaRelative (V2 3 (-3)) (V2 0 (-6))
, Waterfall.bezierTo (V2 3 (-1)) (V2 2.5 (-0.75)) zero
]
heartMask :: Waterfall.Solid
heartMask = let
face = Shape.fromPath heartPath2D
in Waterfall.rotate (unit _x) (pi/2) $ Waterfall.prism 20 face
heart :: Waterfall.Solid
heart = let
r2 = 8 :: Double
face = Waterfall.uScale2D r2 $ Waterfall.unitCircle
half = Waterfall.sweep heartPath face
otherHalf = Waterfall.sweep (Waterfall.rotate (V3 1 0 1) (pi) heartPath) face
sphere = Waterfall.uScale r2 Waterfall.unitSphere
end = pathFactor *^ V3 5 0 5
in half <> otherHalf <> sphere <> Waterfall.translate end sphere
heartPositive :: Waterfall.Solid
heartPositive = heart `Waterfall.difference` heartMask
heartNegative :: Waterfall.Solid
heartNegative = heart `Waterfall.intersection` heartMask
-- 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)
tslotHeart :: Waterfall.Solid
tslotHeart =
let block =
Waterfall.roundFillet 2 .
Waterfall.translate (5 * unit _z) .
Waterfall.scale (V3 25 25 20) $
Waterfall.centeredCube
positionedHeart = Waterfall.translate (V3 0 0 18.5) heartPositive
in (block `Waterfall.union` positionedHeart) `Waterfall.difference` tSlotHole
halfBlock :: Waterfall.Solid
halfBlock = Waterfall.uScale 1000 $ Waterfall.translate (0.5 *^ unit _y) Waterfall.centeredCube
main :: IO ()
main = do
let stlRes = 0.1
Waterfall.writeSTL stlRes "tslot-heart.stl" tslotHeart
Waterfall.writeSTL stlRes "tslot-heart-half-A.stl" (tslotHeart `Waterfall.difference` halfBlock)
Waterfall.writeSTL stlRes "tslot-heart-half-B.stl" (tslotHeart `Waterfall.intersection` halfBlock)
Waterfall.writeSTL stlRes "tslot-heart-clip.stl" heartNegative
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment