module Gamgine.Math.Box where
#include "Gamgine/Utils.cpp"
import Data.Maybe
import qualified Data.List as L
import Gamgine.Math.Vect as V
import Gamgine.Math.Utils
import Gamgine.Utils
IMPORT_LENS_AS_LE
data Box = Box {
minPt :: Vect,
maxPt :: Vect
} deriving (Show, Read)
LENS(minPt)
LENS(maxPt)
center :: Box -> Vect
center b = minPt b + halfs b
halfs :: Box -> Vect
halfs (Box minPt maxPt) = (maxPt minPt) * 0.5
intersects :: Box -> Box -> Bool
Box min1 max1 `intersects` Box min2 max2 =
not $ V.any (>) min2 max1 || V.any (<) max2 min1
inside :: Box -> Box -> Bool
Box min1 max1 `inside` Box min2 max2 =
V.all (>=) min1 min2 && V.all (<=) max1 max2
moveBy :: Box -> Vect -> Box
Box min max `moveBy` v = Box (min + v) (max + v)
extendBy :: Box -> Box -> Box
Box min1 max1 `extendBy` Box min2 max2 =
Box (V.minVec min1 min2) (V.maxVec max1 max2)
contains :: Box -> Vect -> Bool
contains (Box min max) v =
V.all (>=) v min && V.all (<=) v max
bound :: [Box] -> Box
bound [] = Box (V.v3 0 0 0) (V.v3 0 0 0)
bound (b:bs) = L.foldr extendBy b bs
distance :: Box -> Box -> Vect
distance b1 b2 = (abs $ center b2 center b1) (halfs b1 + halfs b2)
minOverlap :: Box -> Box -> Vect
minOverlap (Box min1 max1) (Box min2 max2) = V.fromList $ L.map overlap [0..2]
where
overlap dim =
let v1@(minv1, maxv1) = (getElem dim min1, getElem dim max1)
v2@(minv2, maxv2) = (getElem dim min2, getElem dim max2)
in if maxv1 < minv2 || minv1 > maxv2
then 0
else let minv1Outside = minv1 < minv2
maxv1Outside = maxv1 > maxv2
v1Inside = not minv1Outside && not maxv1Outside
o | v1Inside = insideOverlap v1 v2
| minv1Outside = minOutsideOverlap v1 v2
| maxv1Outside = maxOutsideOverlap v1 v2
in o
insideOverlap (minv1, maxv1) (minv2, maxv2) =
let leftDist = maxv1 minv2
rightDist = maxv2 minv1
o | leftDist < rightDist = leftDist
| otherwise = rightDist
in o
minOutsideOverlap (_, maxv1) (minv2, _) = (maxv1 minv2)
maxOutsideOverlap (minv1, _) (_, maxv2) = maxv2 minv1
type Tuple3d = (Double,Double,Double)
fromTuples :: (Tuple3d, Tuple3d) -> Box
fromTuples (t1, t2) = Box (V.fromTuple t1) (V.fromTuple t2)
toTuples :: Box -> (Tuple3d, Tuple3d)
toTuples (Box minPt maxPt) = (V.toTuple minPt, V.toTuple maxPt)