-- Michael Beaton -- s0561976 -- import LSystem brown,silver,yellow :: Pen brown = Colour 0.5 0.2 0.0 silver = Colour 0.5 0.5 0.5 yellow = Colour 1.0 1.0 0.0 -- 1. join :: [Command] -> Command join cs = foldr1 (:#) cs -- 2. split :: Command -> [Command] split (c:#cs) = reverse(cs : reverse(split c)) split x = x : [] -- 3. copy :: Int -> Command -> Command copy x c = join (replicate x c) -- 4. hexagon :: Distance -> Command hexagon d = copy 6 (Go d :# Turn 60) -- 5. polygon :: Distance -> Int -> Command polygon d x = copy x (Go d :# Turn (360/(fromIntegral x))) -- 6. spiral :: Distance -> Int -> Distance -> Angle -> Command spiral d x e y = join [ Go (d - fromIntegral a*e) :# Turn y | a <- [0..(x-1) ]] -- 7. optimise :: Command -> Command optimise c = join (rmRedundant(opt (rmRedundant(split c)))) opt :: [Command] -> [Command] opt [] = [] opt ((Turn x):((Turn y):cs)) = opt (Turn (x+y) : cs) opt ((Turn x):((Go y):cs)) = Turn x : opt((Go y):cs) opt ((Go x):((Go y):cs)) = opt (Go (x+y) : cs) opt ((Go x):((Turn y):cs)) = Go x : opt((Turn y):cs) opt (c:cs) = c : opt cs rmRedundant :: [Command] -> [Command] rmRedundant cs = [ ds | ds <- cs, ds /= Go 0, ds /= Turn 0, ds /= Sit ] -- 8. arrowhead :: Int -> Command arrowhead x = GrabPen silver :# f x where f 0 = Go 10 f (x+1) = g x :# p :# f x :# p :# g x g 0 = Go 10 g (x+1) = f x :# n :# g x :# n :# f x p = Turn 60 n = Turn (-60) -- 9. branch :: Int -> Command branch x = GrabPen brown :# g x where f 0 = Go 10 f (x+1) = f x :# f x g 0 = Go 10 g (x+1) = f x :# n :# Branch (Branch(g x) :# p :# g x) :# p :# f x :# Branch(p :# f x :# g x) :# n :# g x n = Turn 22.5 p = Turn (-22.5) -- 10. hilbert :: Int -> Command hilbert x = l x where l 0 = GrabPen red :# Go 10 l (x+1) = p :# r x :# f x :# n :# l x :# f x :# l x :# n :# f x :# r x :# p r 0 = GrabPen blue :# Go 10 r (x+1) = n :# l x :# f x :# p :# r x :# f x :# r x :# p :# f x :# l x :# n f x = Go 10 n = Turn 90 p = Turn (-90) -- Competition Entry -- Type 'bart' at the prompt to display -- Not a particularly complicated picture but will hopefully raise a smile! bl :: Command bl = GrabPen black ni :: Command ni = GrabPen Inkless ye :: Command ye = GrabPen yellow re :: Command re = GrabPen red bart :: IO() bart = display 0.5 (ye :# Go 500 :# Turn 135 :# (copy 8 (Go 30 :# Turn (-90) :# Go 30 :# Turn 90)) :# Turn 45 :# Go 500 :# Turn 45 :# Go 20 :# Turn 45 :# Go 312 :# Turn 45 :# Go 20 :# ni :# Turn 45 :# Go 220 :# Turn 90 :# Go 20 :# Turn (-90) :# bl :# (spiral 20 20 0 18) :# ni :# Turn 90 :# Go 292 :# Turn (-90) :# bl :# (spiral 20 20 0 (-18)) :# ni :# Turn (-90) :# Go 100 :# bl :# Turn 90 :# (spiral 10 10 0 36) :# ni :# Turn (-90) :# Go 150 :# Turn 90 :# bl :# (spiral 10 10 0 (-36)) :# ni :# Turn 180 :# Go 140 :# Turn (-90) :# re :# Go 140 :# Turn 135 :# Go 101 :# Turn 90 :# Go 101 :# ni :# Go 100 :# bl :# Go 50 :# ni :# Go 50 :# bl :# Turn 45 :# Go 30 :# Turn (-90) :# Go 15 :# ni :# Turn(-90) :# Go 15 :# Turn (-90) :# bl :# Go 15 :# Turn 90 :# Go 15 :# Turn 90 :# Go 20 :# Turn 60 :# Go 35 :# Turn (-120) :# Go 35 :# Turn 60 :# Go 20 :# Turn 90 :# Go 30 :# Turn 90 :# Go 10 :# Turn 180 :# Go 20 :# ni :# Turn 225 :# Go 90 :# Turn (-135) :# bl :# Go 30 :# Turn (-135) :# Go 20 :# Turn 90 :# Go 20 :# Turn (-135) :# Go 30 :# Turn 90 :# Go 20 :# Turn 90 :# Go 15 :# Turn 45 :# Go 10 :# Turn 180 :# Go 10 :# Turn 90 :# Go 10 :# ni :# Turn 180 :# Go 80 :# bl :# Go 15 :# Turn 90 :# Go 15 :# Turn (-90) :# Go 15 :# Turn 135 :# ni :# Go 20 :# bl :# Turn 90 :# Go 30 :# Turn 180 :# Go 15 :# Turn 90 :# Go 15 :# Turn (-90) :# Go 15 :# ni :# Turn 90 :# Go 15 :# Turn 90 :# bl :# (spiral 10 10 0 90) :# ni :# Turn (90) :# Go 20 :# Turn 90 :# bl :# Go 15 :# Turn (-90) :# Go 15 :# ni :# Go 10 :# bl :# Go 20 :# Turn 180 :# Go 10 :# Turn 90 :# Go 15 :# ni :# Turn 90 :# Go 20 :# bl :# Turn 45 :# Go 15 :# Turn 90 :# Go 15 :# Turn (-90) :# Go 15)