packages feed

hps-0.1: Help/Fractal.hs

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)