-- | -- Module : Cartesian.Plane.BoundingBox -- Description : -- Copyright : (c) Jonatan H Sundqvist, 2015 -- License : MIT -- Maintainer : Jonatan H Sundqvist -- Stability : experimental|stable -- Portability : POSIX (not sure) -- -- Created September 7 2015 -- TODO | - Corner lenses -- - -- SPEC | - -- - -------------------------------------------------------------------------------------------------------------------------------------------- -- GHC Pragmas -------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------- -- API -------------------------------------------------------------------------------------------------------------------------------------------- module Cartesian.Plane.BoundingBox (module Cartesian.Plane.Types, module Cartesian.Plane.BoundingBox, module Cartesian.Plane.BoundingBox.Lenses) where -------------------------------------------------------------------------------------------------------------------------------------------- -- We'll need these -------------------------------------------------------------------------------------------------------------------------------------------- import Data.Complex import Data.Functor ((<$>)) import Data.List (sort) import Control.Lens import Cartesian.Plane.Types import Cartesian.Plane.BoundingBox.Lenses import Cartesian.Plane.Utilities -------------------------------------------------------------------------------------------------------------------------------------------- -- Functions -------------------------------------------------------------------------------------------------------------------------------------------- -- Convenience constructors ---------------------------------------------------------------------------------------------------------------- -- | -- TODO: Better name (?) -- TODO: Don't make assumptions about WHICH corners they are (✓) fromCorners :: RealFloat f => Complex f -> Complex f -> BoundingBox f fromCorners nw@(n:+w) se@(s:+e) = let size = dotmap abs (se-nw) in BoundingBox { _centre=dotwise min nw se+size*(0.5:+0.0), _size=size } -- | Creates a bounding box from a topleft and size vector. fromCornerAndSize :: RealFloat f => Complex f -> Complex f -> BoundingBox f fromCornerAndSize nw size' = BoundingBox { _centre=nw+size'*0.5, _size=size' } -- | Top Left Bottom Right fromSides :: RealFloat f => f -> f -> f -> f -> BoundingBox f fromSides top left bottom right = fromCorners (left:+top) (right:+bottom) -- Booleans -------------------------------------------------------------------------------------------------------------------------------- -- | intersect :: (RealFloat f, Ord f) => BoundingBox f -> BoundingBox f -> Maybe (BoundingBox f) intersect a b = do (left', right') <- overlap (a^.left, a^.right) (b^.left, b^.right) (top', bottom') <- overlap (a^.top, a^.bottom) (b^.top, b^.bottom) return $ fromSides top' left' bottom' right' where overlap (a, b) (c, d) | min (a, b) (c, d) == (a', b') = Just (b', c') | otherwise = Nothing where [a', b', c', d'] = sort [a, b, c, d]