-- | Simple library for 2D shapes. Shallow embedding. module Shape.Shallow ( -- * Types Shape -- abstract -- * Constructor functions , empty, disc, square -- * Primitive combinators , transform, translate , union, intersect, invert -- * Run functions , inside ) where import Matrix newtype Shape = Shape (Point -> Bool) -- * Creation functions empty :: Shape empty = Shape $ \_ -> False disc :: Shape disc = Shape $ \p -> ptX p ^ 2 + ptY p ^ 2 <= 1 square :: Shape square = Shape $ \p -> abs (ptX p) <= 1 && abs (ptY p) <= 1 -- * Primitive combinators -- | Transform a shape with a matrix. transform :: Matrix -> Shape -> Shape transform m sh = Shape $ \p -> (m' `mul` p) `inside` sh where m' = inv m -- the point is transformed with the inverse matrix -- | To represent translations as matrix transformations we would need -- to add another dimension to the matrices (excercise). translate :: Vec -> Shape -> Shape translate v sh = Shape $ \p -> inside (p `sub` v) sh union :: Shape -> Shape -> Shape union sh1 sh2 = Shape $ \p -> inside p sh1 || inside p sh2 intersect :: Shape -> Shape -> Shape intersect sh1 sh2 = Shape $ \p -> inside p sh1 && inside p sh2 invert :: Shape -> Shape invert sh = Shape $ \p -> not (inside p sh) -- * Run function inside :: Point -> Shape -> Bool p `inside` Shape sh = sh p