gloss-accelerate-2.1.0.0: src/Graphics/Gloss/Accelerate/Data/Point.hs
-- |
-- Module : Graphics.Gloss.Accelerate.Data.Point
-- Copyright : [2013..2020] Trevor L. McDonell
-- License : BSD3
--
-- Maintainer : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- 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