module Data.SpaceFillingCurves (
hilbert
, moore
) where
import Control.Applicative (Applicative(..), Alternative(..))
hilbert :: (Eq n, Num n, Fractional f, Alternative p) => n -> f -> f -> f -> f -> f -> f -> p (f,f)
hilbert 0 x0 y0 xi xj yi yj = pure (x0 + (xi + yi) / 2, y0 + (xj + yj) / 2)
hilbert n x0 y0 xi xj yi yj = a <|> b <|> c <|> d
where
a = hilbert (n1) (x0) (y0) (yi/2) (yj/2) (xi/2) (xj/2)
b = hilbert (n1) (x0+xi/2) (y0+xj/2) (xi/2) (xj/2) (yi/2) (yj/2)
c = hilbert (n1) (x0+xi/2+yi/2) (y0+xj/2+yj/2) (xi/2) (xj/2) (yi/2) (yj/2)
d = hilbert (n1) (x0+xi/2+yi) (y0+xj/2+yj) (yi/2) (yj/2) (xi/2) (xj/2)
moore :: (Eq n, Num n, Fractional f, Alternative p) => n -> f -> f -> f -> f -> f -> f -> p (f,f)
moore 0 x0 y0 xi xj yi yj = pure (x0 + (xi + yi) / 2, y0 + (xj + yj) / 2)
moore n x0 y0 xi xj yi yj = a <|> b <|> c <|> d
where
a = hilbert (n1) (x0+xi/2) (y0+xj/2) (xi/2) (xj/2) (yi/2) (yj/2)
b = hilbert (n1) (x0+xi/2+yi/2) (y0+xj/2+yj/2) (xi/2) (xj/2) (yi/2) (yj/2)
c = hilbert (n1) (x0+xi/2+yi) (y0+xj/2+yj) (xi/2) (xj/2) (yi/2) (yj/2)
d = hilbert (n1) (x0+xi/2+yi/2) (y0+xj/2+yj/2) (xi/2) (xj/2) (yi/2) (yj/2)