module LSystem.LSystem where
import Data.CG.Minus
import LSystem.Turtle
import qualified Data.Map as M
type Element = Char
type Axiom = [Element]
type Rules = M.Map Element Axiom
data LSystem = LSystem Axiom Rules deriving (Eq,Show)
lSystem :: Axiom -> [(Element,[Element])] -> LSystem
lSystem a rs = LSystem a (M.fromList rs)
getRule :: Rules -> Element -> [Element]
getRule rs c = M.findWithDefault [c] c rs
applyRule :: [Element] -> Rules -> [Element]
applyRule a rs = concatMap (getRule rs) a
expand :: LSystem -> Int -> [Element]
expand (LSystem a rs) n =
case n of
0 -> a
_ -> expand (LSystem (applyRule a rs) rs) (n 1)
stateT :: Element -> Turtle -> Turtle
stateT e =
case e of
'+' -> turnRight
'-' -> turnLeft
'|' -> turnBack
'>' -> incrLine
'<' -> decrLine
'[' -> push
']' -> pop
'f' -> forward
_ -> id
cmd :: (Turtle -> b -> (Turtle,b)) -> Element -> Turtle -> b -> (Turtle,b)
cmd f e t i =
case e of
'F' -> f t i
_ -> (stateT e t, i)
render :: b -> (b -> Pt R -> Pt R -> b) -> [Element] -> Turtle -> b
render i f l t =
let g (u,j) c = cmd (stepTurtle f) c u j
in snd (foldl g (t, i) l)