module Fractal (fractal, fractalArrow, sierpinski) where import Graphics.PS -- | ftp://ftp.scsh.net/pub/scsh/contrib/fps/doc/examples/fractal-sqr.html fractal :: Pt -> Pt -> Int -> [(Pt, Pt)] fractal p1 p2 0 = [(p1, p2)] fractal p1 p2 d = fractal p1 p3 (d - 1) ++ fractal p3 p2 (d - 1) where (Pt x1 y1) = p1 (Pt x2 y2) = p2 x3 = ((x1 + x2) / 2) + ((y2 - y1) / 2) y3 = ((y1 + y2) / 2) - ((x2 - x1) / 2) p3 = Pt x3 y3 -- | ftp://ftp.scsh.net/pub/scsh/contrib/fps/doc/examples/fractal-arrow.html fractalArrow :: Double -> Int -> Path fractalArrow h d = (translate x y . scale h h) a where x = (576 - h) / 2 + h / 2 y = (720 - h) / 2 a = unitArrow d unitArrow :: Int -> Path unitArrow 1 = MoveTo (Pt 0 0) +++ LineTo (Pt 0 1) unitArrow d = unitArrow 1 +++ (translate 0 1 . rotate cw) sa +++ (translate 0 1 . rotate ccw) sa where s = 0.6 sa = scale s s (unitArrow (d - 1)) cw = - (radians 135) ccw = - cw -- | Equilateral right angled triangle erat :: Pt -> Double -> Path erat (Pt x y) n = polygon [Pt x y, Pt (x+n) y, Pt x (y+n)] -- | Sierpinski triangle. sierpinski :: Pt -> Double -> Double -> Path sierpinski p n limit | n <= limit = erat p n | otherwise = t1 +++ t2 +++ t3 where m = n / 2 (Pt x y) = p s q = sierpinski q m limit t1 = s p t2 = s (Pt x (y + m)) t3 = s (Pt (x + m) y)