Happy Haskmas!
At the last Melbourne Haskell Meetup we got into the spirit by making Christmas trees in Haskell.
However, I recently have access to a 3D printer, and I’ve long wanted an excuse to try and use ImplicitCAD, so I set about trying to make a 3D version of Lyndon’s logo.
So of course, I love stack I created a new simple project with stack new and got started.
It turns out that ImplicitCAD has a pretty nice and reasonably intuitive interface (similar to the code that one would write into OpenSCAD).
I built the 3D version of the logo by moving around rectangles, and by extruding a hand-drawn shape.
The cool thing about generating this image in fully-feature programming language is that I can build a tree of any size I like!
Here’s the (pretty verbose) code that gets me a tree of arbitrary depth:
ntree :: Integer -> SymbolicObj3
ntree n = finalObj
where
dec = 0.8
ratios = 0 : [dec^j | j <- [0..(n-2)]]
-- build up logo structure
((lx, ly, lz), objs) = foldl f ((0, 0, 0), []) (zip [0..(n-1)] ratios)
-- position of logos
(x,y,z) = (40, 4, 0)
f :: ((ℝ, ℝ, ℝ), [SymbolicObj3]) -> (Integer, Float) -> ((ℝ, ℝ, ℝ), [SymbolicObj3])
f ((x', y', z'), xs) (j, r) =
let newPos = (x' + r*x, y' + r*y, z' + r*z)
s = dec ^ j
loc = if (even j) then R else L
obj3 = translate newPos $ scale (s, s, s) (logoBauble loc)
in (newPos, obj3 : xs)
-- star
(a,b,c) = (40.5, 24.5, 0)
starScale = dec ** (fromIntegral (n-3))
posScale = dec ** (fromIntegral n)
starObj = translate (lx + (posScale * a), ly + (posScale * b), lz + (posScale * c))
$ scale (starScale, starScale, starScale) star
finalObj = union (starObj : objs)Running this with n = 5 gives result in the following render in OpenSCAD:

So there you have it! You can view the source code here: github.com/silky/haskmas or download a ready-to-print STL from Thingiverse.
Have a happy Haskmas! :)