-- Author: Wojciech T Cichon
-- How to run: display comp
import LSystem
import Test.QuickCheck
-- Exercise 1
rec = (Go 3 :#: Turn 4 :#: Go 7 :#: Sit)
rec2 = (Go 3 :#: Go 3 :#:Go 3 :#:Turn 4 :#:Turn 4 :#: Go 7 :#: Sit)
km :: Command -> Command
km x = x:#: x
-- 1a. split
split :: Command -> [Command]
split (p :#: q) = ([p] ++ split q)
split p = [p]
-- 1b. join
join :: [Command] -> Command
join cml= foldr1 (:#:) cml
--1c. testing join, split
prop_join_split:: Command -> Bool
prop_join_split cm = (join (split cm)) == (cm)
-- Exercise 2
-- 2a. copy
copy :: Integer -> Command -> Command
copy 1 cmd = cmd
copy x cmd = cmd :#: (copy (x-1) cmd)
-- 2b. pentagon
pentagon :: Distance -> Command
pentagon x =( copy 5 (Go x :#: Turn 72))
-- 2c. polygon
polygon :: Distance -> Integer -> Command
polygon a s = ( copy s (Go a :#: (Turn (360/(fromInteger s)))))
-- Exercise 3
-- spiral
spiral :: Distance -> Int -> Distance -> Angle -> Command
spiral side 1 step angle = (Go side :#: Turn angle)
spiral side n step angle = (Go side :#: Turn angle)
:#:(spiral (side+step) (n-1) step angle)
-- Exercise 4
-- optimise
optimise :: Command -> Command
optimise (Turn 0 :#: cmd) = (optimise cmd)
optimise (Go 0 :#: cmd) = (optimise cmd)
optimise ((Go a) :#: (Go b) :#: (cm)) = optimise ((Go (a+b)) :#: cm)
optimise ((Go a) :#: (Go b)) = (Go (a+b))
optimise ((Go a) :#: cmd) = Go a :#: (optimise cmd)
optimise ((Turn a) :#: (Turn b) :#: (cm)) = optimise ((Turn (a+b)) :#: cm)
optimise ((Turn a) :#: (Turn b)) = (Turn (a+b))
optimise ((Turn a) :#: cmd) = Turn a :#: (optimise cmd)
optimise (Sit :#: cmd) = (optimise cmd)
optimise (Go 0) = Sit
optimise (Turn 0) = Sit
optimise cm = cm
-- L-Systems
trian :: Int -> Command
trian x = p :#: f x
where
f 0 = Go 4
f (x+1) = f x :#: p :#: f x :#: n :#: f x :#: n :#: f x :#: p :#: f x
n = Turn 90
p = Turn (-90)
-- angle: 90
-- start: +f
-- f → f+f-f-f+f
tree1 :: Int -> Command
tree1 x = f x
where
f 0 = GrabPen red :#: Go 4
f (x+1) = g x :#: Branch (n :#: f x)
:#: Branch (p :#: f x)
:#: Branch (g x :#: f x)
g 0 = GrabPen blue :#: Go 4
g (x+1) = g x :#: g x
n = Turn 45
p = Turn (-45)
-- 5. arrowhead
arrowhead :: Int -> Command
arrowhead x = g 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)
-- 6. snowflake
snowflake :: Int -> Command
snowflake x = f x :#:p:#:p:#: f x :#: p:#:p :#:f x:#:p:#:p
where
f 0 = Go 10
f (x+1) = f x :#:n :#: f x :#: p:#:p :#:f x :#:n :#: f x
p = Turn 60
n = Turn (-60)
-- 7. hilbert
hilbert :: Int -> Command
hilbert x = l x
where
f = Go 10
l 0 = Sit
l (x+1) = p:#: r x :#: f :#: n :#: l x :#: f:#: l x :#: n:#: f :#: r x :#: p
r 0 = Sit
r (x+1) = n:#: l x :#: f :#: p :#: r x :#: f:#: r x :#: p:#: f :#: l x :#: n
p = Turn 90
n = Turn (-90)
-- Other Stuff
-- gosper
gosper :: Int -> Command
gosper x = f x
where
f 0 = Go 10
f (x+1) = f x :#: p :#: g x :#: p:#: p:#: g x :#: n :#: f x :#: n :#: n :#: f x :#: f x :#: n :#: g x :#: p
g 0 = Go 10
g (x+1) = n :#: f x :#: p:#: g x :#: g x :#: p :#: p :#: g x :#: p :#: f x :#: n :#: n :#: f x :#: n :#: g x
p = Turn 60
n = Turn (-60)
-- cross
cross :: Int -> Command
cross x = f x :#: n :#: f x :#: n :#: f x :#: n :#: f x :#: n
where
f 0 = Go 10
f (x+1) = f x :#: n :#: f x :#: p :#:f x :#: p :#: f x :#: f x :#:n :#: f x :#: n :#: f x :#: p :#: f x
p = Turn 90
n = Turn (-90)
comp:: Command
comp = (cirRGB :#: Go 12 :#: Turn (-17) :#: showAlph)
-- Competition Stuff
goBack:: Float -> Command
goBack x = GrabPen Inkless :#: Turn 180 :#: Go x :#: Turn 180
circle:: Float -> Command
circle r = copy 360 (Turn 1 :#: Go (2*pi*r/360))
penRed:: Integer -> Command
penRed x = GrabPen (Colour (fromInteger (x)/1200) (fromInteger (1200 - x)/1200) 0)
penGreen:: Integer -> Command
penGreen x = GrabPen (Colour 0 (fromInteger (x)/1200) (fromInteger (1200 - x)/1200))
penBlue:: Integer -> Command
penBlue x = GrabPen (Colour (fromInteger (1200 - x)/1200) 0 (fromInteger (x)/1200))
cirR2G:: Command
cirR2G= (join [ Turn 0.1 :#: penRed x:#: Go 10 :#: goBack 10 | x<-[1..1118]])
cirB2R:: Command
cirB2R= (join [ Turn 0.1 :#: penBlue x:#: Go 10 :#: goBack 10 | x<-[1..1118]])
cirG2B:: Command
cirG2B= (join [ Turn 0.1 :#: penGreen x:#: Go 10 :#: goBack 10 | x<-[1..1118]])
cirRGB:: Command
cirRGB= cirR2G :#: cirB2R :#: cirG2B
-- //
showAlph :: Command
showAlph = join [charToCMD ch 2 green | ch <- ['A'..'Z']]
showStr :: [Char] -> Command
showStr str = join [charToCMD ch 2 green | ch <- str]
charToCMD :: Char -> Float -> Pen-> Command
charToCMD 'A' size pen =GrabPen pen :#: Turn (-20) :#: Go size :#: Turn (-140) :#: Go size :#: Turn 180 :#:Go (size/2) :#: Turn 70 :#: Go (sin (pi/ (180/20)) *(size)) :#: Turn 180 :#: Go (sin (pi/ (180/20)) *(size)) :#: Turn (-70) :#: Go (size/2) :#:Turn (70) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'B' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: copy 178 (Turn (-1) :#: Go (2*pi*(size/4)/360)) :#: Turn 180 :#: copy 184
(Turn (-1) :#: Go (2*pi*(size/4)/360)) :#: GrabPen Inkless :#: Turn 182 :#: Go (size/3) :#: Turn 90
charToCMD 'C' size pen = GrabPen Inkless :#: Turn (-90) :#: Go (size/2) :#: Turn (180) :#: GrabPen pen :#: (copy 180 (Turn (-1) :#: Go (2*pi*(size/2)/360))):#: GrabPen Inkless :#: Turn (-90) :#: Go size :#: Turn (90) :#: Go (size/10) :#: Turn 90
charToCMD 'D' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: copy 180 (Turn (-1) :#: Go (2*pi*(size/2)/360)) :#: GrabPen Inkless :#: Turn 180 :#: Go (size/1.9) :#: Turn 90
charToCMD 'E' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: Go (size/2) :#: Turn (180) :#: Go (size/2) :#: Turn (90) :#: Go (size/2) :#: Turn (90) :#: Go (size/3) :#: Turn (180) :#: Go (size/3) :#: Turn (90) :#: Go (size/2) :#: Turn (90) :#: Go (size/2) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'F' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: Go (size/2) :#: Turn (180) :#: Go (size/2) :#: Turn (90) :#: Go (size/2) :#: Turn (90) :#: Go (size/3) :#: Turn (180) :#: GrabPen Inkless :#: Go (size/3) :#: Turn (90) :#: Go (size/2) :#: Turn (90) :#: Go (size/2) :#: Go (size/10) :#: Turn 90
charToCMD 'G' size pen = GrabPen Inkless :#: Turn (-90) :#: Go (size/2) :#: GrabPen pen :#: Turn 90 :#: Go (size/2) :#: Turn 90 :#: Go (size/4) :#: Turn 180 :#: Go (size/4) :#:Turn (-90) :#:Go (size/2) :#: Turn (-90) :#: (copy 180 (Turn (-1) :#: Go (2*pi*(size/2)/360))):#: GrabPen Inkless :#: Turn (-90) :#: Go size :#: Turn (90) :#: Go (size/10) :#: Turn 90
charToCMD 'H' size pen = GrabPen pen :#: Go size :#: Turn (180) :#: Go (size/2) :#: Turn (90) :#: Go (size/3) :#: Turn (90) :#: Go (size/2) :#: Turn (180) :#: Go (size) :#: Turn (90) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'I' size pen = GrabPen pen :#: Go size :#: Turn (180) :#: Go (size) :#: Turn (90) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'J' size pen = GrabPen Inkless :#: Turn (-90) :#: Go (2*size/3) :#: Turn 90 :#: Go (size/3) :#: GrabPen pen :#: Go (2*(size/3)) :#: Turn 180 :#: Go (2*(size/3)) :#: (copy 180 (Turn (-1) :#: Go (2*pi*(size/3)/360))) :#: GrabPen Inkless :#: Turn (180) :#: Go (size/3) :#: Turn (90) :#: Go (23*size/30) :#: Turn 90
charToCMD 'K' size pen = GrabPen pen :#: Go size :#: Turn (180) :#: Go (size/2) :#: Turn (135) :#: Go ((size/2)*(sqrt 2)) :#: Turn (180):#: Go ((size/2)*(sqrt 2)) :#: Turn (90) :#: Go ((size/2)*(sqrt 2)) :#: Turn (45) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'L' size pen = GrabPen pen :#: Go size :#: Turn (180) :#: Go (size) :#: Turn (90) :#: Go (size/2) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'M' size pen = GrabPen pen :#: Go size :#: Turn (-150) :#: Go (size/3) :#: Turn (120) :#: Go (size/3) :#: Turn (-150) :#: Go (size) :#: Turn (90) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'N' size pen = GrabPen pen :#: Go size :#: Turn (-150) :#: Go (2* size / (sqrt 3)) :#: Turn (150) :#: Go (size) :#: Turn (180) :#: Go (size) :#: Turn (90) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'O' size pen = GrabPen Inkless :#: Turn (-90) :#: Go (size/2) :#: Turn (180) :#: GrabPen pen :#: (copy 360 (Turn (-1) :#: Go (2*pi*(size/2)/360))):#: GrabPen Inkless :#: Turn 180 :#: Go (6*size/10) :#: Turn 90
charToCMD 'P' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: copy 180 (Turn (-1) :#: Go (2*pi*(size/4)/360)) :#: Turn 90 :#: Go (size/2) :#: GrabPen Inkless :#: Turn 90 :#: Go (size/3) :#: Turn 90
charToCMD 'R' size pen = GrabPen pen :#: Go size :#: Turn (-90) :#: copy 180 (Turn (-1) :#: Go (2*pi*(size/4)/360)) :#: Turn (135) :#:Go ((size/2)*(sqrt 2)) :#: Turn (45) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'S' size pen = GrabPen Inkless :#: Go (size/4) :#: GrabPen pen :#: Turn 180 :#: (copy 270 (Turn 1 :#: Go (2*pi*(size/4)/360))):#: (copy 270 (Turn (-1) :#: Go (2*pi*(size/4)/360))) :#: GrabPen Inkless :#: Go (3*size/4) :#: Turn 90 :#: Go (size/10):#: Turn 90
charToCMD 'T' size pen = GrabPen Inkless :#: Go (size) :#: Turn (-90):#: GrabPen pen :#: Go (size/2) :#: Turn (180) :#: Go (size/4) :#: Turn (90) :#: Go size :#: Turn 90 :#: GrabPen Inkless :#: Go (6*size/10) :#: Turn 90
charToCMD 'U' size pen = GrabPen Inkless :#: Go (size/3) :#: GrabPen pen :#: Go (2*size/3) :#: Turn 180 :#: Go (2*size/3) :#: (copy 180 (Turn (1) :#: Go (2*pi*(size/3)/360))) :#: Go (2*size/3) :#: Turn (180) :#: GrabPen Inkless :#: Go (size) :#: Turn (90) :#: Go (size/10) :#: Turn 90
charToCMD 'V' size pen = GrabPen Inkless :#: Go size :#: GrabPen pen :#: Turn (-160) :#: Go size :#: Turn (140) :#: Go size :#: Turn (-160) :#: GrabPen Inkless :#: Go size :#: Turn 90 :#: Go (size/10) :#: Turn 90
charToCMD 'W' size pen = GrabPen pen :#: Go size :#: Turn 180:#: Go size :#: Turn (150) :#: Go (size/3) :#: Turn (-120) :#: Go (size/3) :#: Turn (150) :#: Go (size) :#: Turn 180:#: Go size :#: Turn (90) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'X' size pen = GrabPen pen :#: Turn (-30) :#: Go (size*(sqrt 5)/2) :#: Turn 120 :#:GrabPen Inkless :#: Go (size*(sqrt 5)/4) :#: GrabPen pen :#: Turn 120 :#: Go (size*(sqrt 5)/2) :#: Turn 60:#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD 'Y' size pen = GrabPen Inkless :#: Go size :#: GrabPen pen :#: Turn (-135) :#: Go (size*(sqrt 2)/4) :#: Turn 90 :#: Go (size*(sqrt 2)/4) :#: Turn 180:#: Go (size*(sqrt 2)/4) :#: Turn 45 :#: Go (3*size/4) :#: Turn 90 :#: GrabPen Inkless :#: Go (3*size/10) :#: Turn 90
charToCMD 'Z' size pen = GrabPen Inkless :#: Go size :#: Turn (-90) :#: GrabPen pen :#: Go (size/(sqrt 3)) :#: Turn (-120) :#: Go (size*2/(sqrt 3)) :#: Turn 120 :#: Go (size/(sqrt 3)) :#: GrabPen Inkless :#: Go (size/10) :#: Turn 90
charToCMD ch size pen = Sit