module Data.BoundingBox.B3 where
import Data.Vector.Class
import Data.Vector.V3
import qualified Data.BoundingBox.Range as R
data BBox3 = BBox3 {minX, minY, minZ, maxX, maxY, maxZ :: !Scalar} deriving (Eq, Show)
rangeX :: BBox3 -> R.Range
rangeX b = R.Range (minX b) (maxX b)
rangeY :: BBox3 -> R.Range
rangeY b = R.Range (minY b) (maxY b)
rangeZ :: BBox3 -> R.Range
rangeZ b = R.Range (minZ b) (maxZ b)
rangeXYZ :: R.Range -> R.Range -> R.Range -> BBox3
rangeXYZ (R.Range x0 x1) (R.Range y0 y1) (R.Range z0 z1) = BBox3 x0 y0 z0 x1 y1 z1
bound_corners :: Vector3 -> Vector3 -> BBox3
bound_corners (Vector3 xa ya za) (Vector3 xb yb zb) = BBox3 (min xa xb) (min ya yb) (min za zb) (max xa xb) (max ya yb) (max za zb)
bound_points :: [Vector3] -> BBox3
bound_points ps =
let
xs = map v3x ps
ys = map v3y ps
zs = map v3z ps
in BBox3 (minimum xs) (minimum ys) (minimum zs) (maximum xs) (maximum ys) (maximum zs)
within_bounds :: Vector3 -> BBox3 -> Bool
within_bounds (Vector3 x y z) b =
x `R.within_bounds` (rangeX b) &&
y `R.within_bounds` (rangeY b) &&
z `R.within_bounds` (rangeZ b)
min_point :: BBox3 -> Vector3
min_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x0 y0 z0
max_point :: BBox3 -> Vector3
max_point (BBox3 x0 y0 z0 x1 y1 z1) = Vector3 x1 y1 z1
union :: BBox3 -> BBox3 -> BBox3
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)
in rangeXYZ rx ry rz
isect :: BBox3 -> BBox3 -> Maybe BBox3
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)
return (rangeXYZ rx ry rz)
unions :: [BBox3] -> BBox3
unions bs =
let
minP = map min_point bs
maxP = map max_point bs
in
BBox3
(minimum $ map v3x minP) (minimum $ map v3y minP) (minimum $ map v3z minP)
(maximum $ map v3x maxP) (maximum $ map v3y maxP) (maximum $ map v3z maxP)