module Data.BoundingBox.B4 where
import Data.Vector.Class
import Data.Vector.V4
import qualified Data.BoundingBox.Range as R
data BBox4 = BBox4 {minX, minY, minZ, minW, maxX, maxY, maxZ, maxW :: !Scalar} deriving (Eq, Show)
rangeX :: BBox4 -> R.Range
rangeX b = R.Range (minX b) (maxX b)
rangeY :: BBox4 -> R.Range
rangeY b = R.Range (minY b) (maxY b)
rangeZ :: BBox4 -> R.Range
rangeZ b = R.Range (minZ b) (maxZ b)
rangeW :: BBox4 -> R.Range
rangeW b = R.Range (minW b) (maxW b)
rangeXYZW :: R.Range -> R.Range -> R.Range -> R.Range -> BBox4
rangeXYZW (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) (R.Range w0 w1) = BBox4 x0 y0 z0 w0 x1 y1 z1 w1
bound_corners :: Vector4 -> Vector4 -> BBox4
bound_corners (Vector4 xa ya za wa) (Vector4 xb yb zb wb) =
BBox4 (min xa xb) (min ya yb) (min za zb) (min wa wb) (max xa xb) (max ya yb) (max za zb) (max wa wb)
bound_points :: [Vector4] -> BBox4
bound_points ps =
let
xs = map v4x ps
ys = map v4y ps
zs = map v4z ps
ws = map v4w ps
in BBox4 (minimum xs) (minimum ys) (minimum zs) (minimum ws) (maximum xs) (maximum ys) (maximum zs) (maximum ws)
within_bounds :: Vector4 -> BBox4 -> Bool
within_bounds (Vector4 x y z w) b =
x `R.within_bounds` (rangeX b) &&
y `R.within_bounds` (rangeY b) &&
z `R.within_bounds` (rangeZ b) &&
w `R.within_bounds` (rangeW b)
min_point :: BBox4 -> Vector4
min_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x0 y0 z0 w0
max_point :: BBox4 -> Vector4
max_point (BBox4 x0 y0 z0 w0 x1 y1 z1 w1) = Vector4 x1 y1 z1 w1
union :: BBox4 -> BBox4 -> BBox4
union b0 b1 =
let
rx = (rangeX b0) `R.union` (rangeX b1)
ry = (rangeY b0) `R.union` (rangeY b1)
rz = (rangeZ b0) `R.union` (rangeZ b1)
rw = (rangeW b0) `R.union` (rangeW b1)
in rangeXYZW rx ry rz rw
isect :: BBox4 -> BBox4 -> Maybe BBox4
isect b0 b1 = do
rx <- (rangeX b0) `R.isect` (rangeX b1)
ry <- (rangeY b0) `R.isect` (rangeY b1)
rz <- (rangeZ b0) `R.isect` (rangeZ b1)
rw <- (rangeW b0) `R.isect` (rangeW b1)
return (rangeXYZW rx ry rz rw)
unions :: [BBox4] -> BBox4
unions bs =
let
minP = map min_point bs
maxP = map max_point bs
in
BBox4
(minimum $ map v4x minP) (minimum $ map v4y minP) (minimum $ map v4z minP) (minimum $ map v4w minP)
(maximum $ map v4x maxP) (maximum $ map v4y maxP) (maximum $ map v4z maxP) (maximum $ map v4w maxP)