{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} -- | Module implementing types used for geometry -- bound calculations. module Graphics.Rasterific.PlaneBoundable ( PlaneBound( .. ) , PlaneBoundable( .. ) , boundWidth , boundHeight , boundLowerLeftCorner ) where import Graphics.Rasterific.Linear( V2( .. ) ) import Graphics.Rasterific.Types import Graphics.Rasterific.CubicBezier -- | Represent the minimal axis aligned rectangle -- in which some primitives can be drawn. Should -- fit to bezier curve and not use directly their -- control points. data PlaneBound = PlaneBound { -- | Corner upper left of the bounding box of -- the considered primitives. _planeMinBound :: !Point -- | Corner lower right of the bounding box of -- the considered primitives. , _planeMaxBound :: !Point } deriving (Eq, Show) -- | Extract the width of the bounds boundWidth :: PlaneBound -> Float boundWidth (PlaneBound (V2 x0 _) (V2 x1 _)) = x1 - x0 -- | Extract the height of the bound boundHeight :: PlaneBound -> Float boundHeight (PlaneBound (V2 _ y0) (V2 _ y1)) = y1 - y0 -- | Extract the position of the lower left corner of the -- bounds. boundLowerLeftCorner :: PlaneBound -> Point boundLowerLeftCorner (PlaneBound (V2 x _) (V2 _ y)) = V2 x y instance Semigroup PlaneBound where (<>) (PlaneBound mini1 maxi1) (PlaneBound mini2 maxi2) = PlaneBound (min <$> mini1 <*> mini2) (max <$> maxi1 <*> maxi2) instance Monoid PlaneBound where mappend = (<>) mempty = PlaneBound infPoint negInfPoint where infPoint = V2 (1 / 0) (1 / 0) negInfPoint = V2 (negate 1 / 0) (negate 1 / 0) -- | Class used to calculate bounds of various geometrical -- primitives. The calculated is precise, the bounding should -- be minimal with respect with drawn curve. class PlaneBoundable a where -- | Given a graphical elements, calculate it's bounds. planeBounds :: a -> PlaneBound instance PlaneBoundable Point where planeBounds a = PlaneBound a a instance PlaneBoundable Line where planeBounds (Line p1 p2) = planeBounds p1 <> planeBounds p2 instance PlaneBoundable Bezier where planeBounds (Bezier p0 p1 p2) = planeBounds (CubicBezier p0 p1 p1 p2) instance PlaneBoundable CubicBezier where planeBounds = foldMap planeBounds . cubicBezierBounds instance PlaneBoundable Primitive where planeBounds (LinePrim l) = planeBounds l planeBounds (BezierPrim b) = planeBounds b planeBounds (CubicBezierPrim c) = planeBounds c