module Nxt.Types (Vector2d, Texture(Texture), textureWidth, textureHeight, textureObject, Nxt.Types.Rect(Rect), rectX, rectY, rectWidth, rectHeight, rectRight, rectBottom, rectIntersect, pointInRect, overlapRect, Poly(Poly), polySides, polyVertices, polyIntersect, Direction(DirLeft,DirRight)) where import Graphics.Rendering.OpenGL as GL hiding (Rect) -- Direction data Direction = DirLeft | DirRight -- Texture data Texture = Texture { textureWidth :: GLsizei, textureHeight :: GLsizei, textureObject :: TextureObject } -- Rect data Rect = Rect { rectX :: Double, rectY :: Double, rectWidth :: Double, rectHeight :: Double } deriving Show -- rectRight rectRight :: Rect -> Double rectRight (Rect x _ w _) = x + w -- rectBottom rectBottom :: Rect -> Double rectBottom (Rect _ y _ h) = y + h -- rectIntersect rectIntersect :: Rect -> Rect -> Bool rectIntersect (Rect r1X r1Y r1Width r1Height) (Rect r2X r2Y r2Width r2Height) = not (r1X > (r2X + r2Width) || r2X > (r1X + r1Width) || r1Y > (r2Y + r2Height) || r2Y > (r1Y + r1Height)) -- pointInRect pointInRect :: Vector2d -> Rect -> Bool pointInRect (x, y) (Rect rectXt rectYt width height) = x >= rectXt && x <= (rectXt + width) && y >= rectYt && y <= (rectYt + height) -- overlapRect overlapRect :: Rect -> Rect -> Rect overlapRect (Rect r1x r1y r1Width r1Height) (Rect r2x r2y r2Width r2Height) = Rect x y width height where x = max r1x r2x y = max r1y r2y width = min (r1x + r1Width) (r2x + r2Width) - x height = min (r1y + r1Height) (r2y + r2Height) - r2Height -- Vector2d type Vector2d = (Double, Double) -- Poly data Poly = Poly { polySides :: Int, polyVertices :: [Vector2d] } deriving Show -- dotProduct dotProduct :: Vector2d -> Vector2d -> Double dotProduct (p1X, p1Y) (p2X, p2Y) = p1X * p2X + p1Y * p2Y -- polyIntersect polyIntersect :: Poly -> Poly -> Bool polyIntersect polyA polyB = let polyAVerts = polyVertices polyA polyAPrevVerts = last polyAVerts : init polyAVerts polyAPairVerts = zip polyAPrevVerts polyAVerts polyBVerts = polyVertices polyB polyBPrevVerts = last polyBVerts : init polyBVerts polyBPairVerts = zip polyBPrevVerts polyBVerts normalizeAxis :: (Vector2d, Vector2d) -> Vector2d normalizeAxis (prevVert, vert) = let (ptPrevX, ptPrevY) = prevVert (ptCurrX, ptCurrY) = vert axisX = ptPrevY - ptCurrY axisY = ptCurrX - ptPrevX tmp = sqrt (axisX * axisX + axisY * axisY) in (axisX / tmp, axisY / tmp) projRange :: [Vector2d] -> Vector2d -> (Double,Double) projRange vertices axis = let projLengths = map (`dotProduct` axis) vertices minl = minimum projLengths maxl = maximum projLengths in (minl, maxl) overlap :: (Vector2d, Vector2d) -> Bool overlap pairVerts = not (maxA < minB || minA > maxB) where axis = normalizeAxis pairVerts (minA, maxA) = projRange polyAVerts axis (minB, maxB) = projRange polyBVerts axis in all overlap polyAPairVerts && all overlap polyBPairVerts