{-#LANGUAGE TypeFamilies,FlexibleInstances, FlexibleContexts#-} module Utils.GeometryClass where import Utils.Rectangle import Utils.Point class Point2D a where type ELP a :: * pt :: a -> (ELP a, ELP a) toPt :: (ELP a,ELP a) -> a instance Point2D (Int,Int) where type ELP (Int,Int) = Int pt = id toPt = id instance Point2D (Float,Float) where type ELP (Float,Float) = Float pt = id toPt = id instance Point2D (Double,Double) where type ELP (Double,Double) = Double pt = id toPt = id -- | Extract integer coordinates of a point ipt :: (Point2D a,RealFrac (ELP a)) => a -> (Int,Int) ipt = (\(x,y) -> (round x, round y)) . pt convertPt :: (Point2D a, Point2D b, ELP a ~ ELP b) => a -> b convertPt = toPt . pt class BoundingBox a where type ELBB a :: * bounds :: a -> Rectangle (ELBB a) class FromBounds a where type ELFB a :: * fromBounds :: Rectangle (ELFB a) -> a instance BoundingBox (Rectangle a) where type ELBB (Rectangle a) = a bounds = id instance FromBounds (Rectangle a) where type ELFB (Rectangle a) = a fromBounds = id convertBounds :: (BoundingBox a, FromBounds b, ELBB a ~ ELFB b) => a -> b convertBounds = fromBounds . bounds -- type IntBounded a = (BoundingBox a,Integral (ELBB a)) class Line2D a where type ELL a :: * offsetAngle :: a -> (ELL a, Double) class LineSegment a where type ELS a :: * startEnd :: a -> ((ELS a, ELS a),(ELS a, ELS a)) -- | Typeclass for elements with a size, such as images and matrices. class Sized a where type Size a :: * getSize :: a -> Size a biggerThan :: (Sized a, Sized b, Size a~(Int,Int), Size b ~Size a) => a -> b -> Bool biggerThan a b = w1>=w2 && h1>=h2 where (w1,h1) = getSize a (w2,h2) = getSize b