Calendar 2015 - Lung
Interlocking space filling curves - in the limit the perimeter between adjacent blocks becomes infinite, like a perfect lung for transferring oxygen from air to blood and carbon dioxide in the other direction. Made with the Haskell Diagrams library:
{-# LANGUAGE TypeFamilies, FlexibleContexts #-} import Diagrams.Prelude hiding (E) import Diagrams.Backend.SVG.CmdLine (defaultMain) import Control.Monad.State (state, evalState) import Data.Colour.SRGB (sRGB24) data H = N | E | S | W data T = L | R step L = [L,R,L] step R = [L,R,R,R,L] seed = [R,R,R,R] levels = iterate (concatMap step) seed heading N L = W heading E L = N heading S L = E heading W L = S heading N R = E heading E R = S heading S R = W heading W R = N angle N = 90 @@ deg angle E = 0 @@ deg angle S = -90 @@ deg angle W = 180 @@ deg draw d h = (arcD d a a', h') where a = angleDir $ angle h a' = case d of L -> 90 @@ deg R -> -90 @@ deg h' = heading h d arcD L a b = arc a b arcD R a b = scale (-1) $ arcCW a (rotate b a) draws = mconcat . (`evalState` E) . mapM (state . draw) base = draws (levels !! level) # closeTrail # pathFromTrail # translate (r2 (-1, 0)) # stroke left = base middle = base # scale (sqrt 0.5) # rotate (45 @@ deg) # translateX (2 ^ (level + 1)) right = base # scale 0.5 # translateX (2 ^ level * 3) # translateY (2 ^ level) four = base # scale (sqrt 0.125) # rotate (45 @@ deg) # translateX (3 * 2 ^ level) # translateY (2 ^ (level + 1)) lung = (left # fc r <> middle # fc y <> right # fc g <> four # fc b) # rotate ((atan 5 :: Double) @@ rad) # centerXY # pad 1.01 # lc black # lw 0.1 # bg white # rotate (-90 @@ deg) y = sRGB24 0xff 0xdf 0x80 r = sRGB24 0xff 0x88 0xaa b = sRGB24 0xaa 0xaa 0xff g = sRGB24 0x88 0xff 0xaa level = 4 main = defaultMain lung