Skip to content

Instantly share code, notes, and snippets.

@sordina
Created June 30, 2011 07:18
Show Gist options
  • Save sordina/1055788 to your computer and use it in GitHub Desktop.
Save sordina/1055788 to your computer and use it in GitHub Desktop.
Dragon Curve ASCII
{-
Plotting the dragon curve
=========================
Console Version
http://en.wikipedia.org/wiki/Lindenmayer_system
-}
import Control.Monad
import Control.Arrow
import Data.List
import qualified Data.Set as S
-- Should be 90 degrees, but just playing with it to see what happenes
angle = pi/2.2
data Direction = X | Y | F | P | N deriving (Show, Eq)
dims = (95,33)
-- Magic number: Itteration of the Lindenmayer transform
main = render dims $ normalise ((fromIntegral *** fromIntegral) dims) $ points $ dragon 12
render :: (Int, Int) -> [(Int,Int)] -> IO ()
render (w,h) l =
forM_ [0..h] $ \y -> do
forM_ [0..w] $ \x -> putStr $ if S.member (x,y) s then "X" else " "
putStrLn ""
where s = S.fromList l
normalise :: (Float,Float) -> [(Float,Float)] -> [(Int,Int)]
normalise (w,h) l = map ((\x -> round (x * w / maxx)) *** (\y -> round (y * h / maxy))) l'
where
minx = minimum $ map fst l
miny = minimum $ map snd l
l' = map (subtract minx *** subtract miny) l
maxx = maximum $ map fst l'
maxy = maximum $ map snd l'
points :: [Direction] -> [(Float,Float)]
points l = snd $ foldl' foo (0,[(0,0)]) l
where
foo :: (Float,[(Float,Float)]) -> Direction -> (Float,[(Float,Float)])
foo (a, xs) P = (a + angle, xs)
foo (a, xs) N = (a - angle, xs)
foo (a, xs@((x,y):_)) F = (a, (x + cos a, y + sin a):xs)
foo i _ = i
dragon :: Int -> [Direction]
dragon n = filter (`elem` [F,P,N]) (dragons !! n)
dragons = iterate (concatMap substitute) [F,X]
substitute X = [X,P,Y,F,P]
substitute Y = [N,F,X,N,Y]
substitute x = [x]
{-
XXXXX XXXXX
XXXXXXXXX XXXXXXXXX
XX X XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXX XXXX XXXX
XX XXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX
XXXXX XXXXXXXXXXX XXXXXX XXXXXXXXXXXX XXX
XXXXX XXX XXXXXXXXXXX XXXXXXXXX XXXX XXXXXXXXXX
XXXXXX XX XXXXXXXXXXXXXXXX XXX XXXXXXXXXX
XXXXXXXXXXXXXXX XX XXXXXXXXX
XXXXXXXXXXXXXXXXXXXXX XXXX XXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX XXXXXX X XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXX XXXX
XXXXXXXXXXXXX XXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX
XX XXXXXXXXXXXXX XXX XXXXXXXXXXXX
XXXXXXXXXXXXX XXXXXXXXXXXX
XXX XXX XXX XXX
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment