-- | -- Module : Graphics.Gloss.Accelerate.Data.Point -- Copyright : [2013..2020] Trevor L. McDonell -- License : BSD3 -- -- Maintainer : Trevor L. McDonell -- Stability : experimental -- Portability : non-portable (GHC extensions) -- module Graphics.Gloss.Accelerate.Data.Point ( -- ** Point data type Point, -- ** Point creation makePoint, xyOfPoint, pointOfIndex, -- ** Testing points pointInBox, ) where import Data.Array.Accelerate as A import Data.Array.Accelerate.Linear.V2 import qualified Prelude as P -- | An abstract point value on the xy-plane. -- type Point = V2 Float -- | Make a custom point -- makePoint :: Exp Float -- ^ x-coordinate -> Exp Float -- ^ y-coordinate -> Exp Point makePoint = V2_ -- | Take the components of a point -- xyOfPoint :: Exp Point -> (Exp Float, Exp Float) xyOfPoint (V2_ x y) = (x, y) -- | Convert a two-dimensional index into a point centered in a plane of the -- given width and height. -- pointOfIndex :: Int -- ^ width -> Int -- ^ height -> Exp DIM2 -> Exp Point pointOfIndex sizeX sizeY ix = let -- Size of the raw plane fsizeX, fsizeY :: Float fsizeX = P.fromIntegral sizeX fsizeY = P.fromIntegral sizeY fsizeX2, fsizeY2 :: Exp Float fsizeX2 = constant $ fsizeX / 2 fsizeY2 = constant $ fsizeY / 2 -- Midpoint of plane midX, midY :: Exp Int midX = constant $ sizeX `div` 2 midY = constant $ sizeY `div` 2 -- Centre coordinate in the plane Z :. y :. x = unlift ix x' = A.fromIntegral (x - midX) / fsizeX2 y' = A.fromIntegral (y - midY) / fsizeY2 in makePoint x' y' -- | Test whether a point lies within a rectangular box that is oriented -- on the x-y plane. The points P1-P2 are opposing points of the box, -- but need not be in a particular order. -- -- @ -- P2 +-------+ -- | | -- | + P0 | -- | | -- +-------+ P1 -- @ -- pointInBox :: Exp Point -- ^ point to test -> Exp Point -- ^ corner of box -> Exp Point -- ^ opposite corner of box -> Exp Bool pointInBox (V2_ x0 y0) (V2_ x1 y1) (V2_ x2 y2) = x0 >= min x1 x2 && x0 <= max x1 x2 && y0 >= min y1 y2 && y0 <= max y1 y2