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 {
Box -> Vect
minPt :: Vect,
Box -> Vect
maxPt :: Vect
} deriving (Int -> Box -> ShowS
[Box] -> ShowS
Box -> String
(Int -> Box -> ShowS)
-> (Box -> String) -> ([Box] -> ShowS) -> Show Box
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Box -> ShowS
showsPrec :: Int -> Box -> ShowS
$cshow :: Box -> String
show :: Box -> String
$cshowList :: [Box] -> ShowS
showList :: [Box] -> ShowS
Show, ReadPrec [Box]
ReadPrec Box
Int -> ReadS Box
ReadS [Box]
(Int -> ReadS Box)
-> ReadS [Box] -> ReadPrec Box -> ReadPrec [Box] -> Read Box
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Box
readsPrec :: Int -> ReadS Box
$creadList :: ReadS [Box]
readList :: ReadS [Box]
$creadPrec :: ReadPrec Box
readPrec :: ReadPrec Box
$creadListPrec :: ReadPrec [Box]
readListPrec :: ReadPrec [Box]
Read)
LENS(minPt)
LENS(maxPt)
center :: Box -> Vect
center :: Box -> Vect
center Box
b = Box -> Vect
minPt Box
b Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
+ Box -> Vect
halfs Box
b
halfs :: Box -> Vect
halfs :: Box -> Vect
halfs (Box Vect
minPt Vect
maxPt) = (Vect
maxPt Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
- Vect
minPt) Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
* Vect
0.5
intersects :: Box -> Box -> Bool
Box Vect
min1 Vect
max1 intersects :: Box -> Box -> Bool
`intersects` Box Vect
min2 Vect
max2 =
Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.any Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(>) Vect
min2 Vect
max1 Bool -> Bool -> Bool
|| (Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.any Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(<) Vect
max2 Vect
min1
inside :: Box -> Box -> Bool
Box Vect
min1 Vect
max1 inside :: Box -> Box -> Bool
`inside` Box Vect
min2 Vect
max2 =
(Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.all Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(>=) Vect
min1 Vect
min2 Bool -> Bool -> Bool
&& (Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.all Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(<=) Vect
max1 Vect
max2
moveBy :: Box -> Vect -> Box
Box Vect
min Vect
max moveBy :: Box -> Vect -> Box
`moveBy` Vect
v = Vect -> Vect -> Box
Box (Vect
min Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
+ Vect
v) (Vect
max Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
+ Vect
v)
extendBy :: Box -> Box -> Box
Box Vect
min1 Vect
max1 extendBy :: Box -> Box -> Box
`extendBy` Box Vect
min2 Vect
max2 =
Vect -> Vect -> Box
Box (Vect -> Vect -> Vect
forall {c} {u} {v} {w}. (ZipWith c c c u v w, Ord c) => u -> v -> w
V.minVec Vect
min1 Vect
min2) (Vect -> Vect -> Vect
forall {c} {u} {v} {w}. (ZipWith c c c u v w, Ord c) => u -> v -> w
V.maxVec Vect
max1 Vect
max2)
contains :: Box -> Vect -> Bool
contains :: Box -> Vect -> Bool
contains (Box Vect
min Vect
max) Vect
v =
(Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.all Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(>=) Vect
v Vect
min Bool -> Bool -> Bool
&& (Double -> Double -> Bool) -> Vect -> Vect -> Bool
forall {v1} {a} {b} {c} {u} {v2}.
(Fold v1 Bool, ZipWith a b c u v2 v1) =>
(a -> b -> c) -> u -> v2 -> Bool
V.all Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
(<=) Vect
v Vect
max
bound :: [Box] -> Box
bound :: [Box] -> Box
bound [] = Vect -> Vect -> Box
Box (Double -> Double -> Double -> Vect
V.v3 Double
0 Double
0 Double
0) (Double -> Double -> Double -> Vect
V.v3 Double
0 Double
0 Double
0)
bound (Box
b:[Box]
bs) = (Box -> Box -> Box) -> Box -> [Box] -> Box
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
L.foldr Box -> Box -> Box
extendBy Box
b [Box]
bs
distance :: Box -> Box -> Vect
distance :: Box -> Box -> Vect
distance Box
b1 Box
b2 = (Vect -> Vect
forall a. Num a => a -> a
abs (Vect -> Vect) -> Vect -> Vect
forall a b. (a -> b) -> a -> b
$ Box -> Vect
center Box
b2 Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
- Box -> Vect
center Box
b1) Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
- (Box -> Vect
halfs Box
b1 Vect -> Vect -> Vect
forall a. Num a => a -> a -> a
+ Box -> Vect
halfs Box
b2)
minOverlap :: Box -> Box -> Vect
minOverlap :: Box -> Box -> Vect
minOverlap (Box Vect
min1 Vect
max1) (Box Vect
min2 Vect
max2) = [Double] -> Vect
forall a v. VecList a v => [a] -> v
V.fromList ([Double] -> Vect) -> [Double] -> Vect
forall a b. (a -> b) -> a -> b
$ (Int -> Double) -> [Int] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
L.map Int -> Double
overlap [Int
0..Int
2]
where
overlap :: Int -> Double
overlap Int
dim =
let v1 :: (Double, Double)
v1@(Double
minv1, Double
maxv1) = (Int -> Vect -> Double
forall a v. VecList a v => Int -> v -> a
getElem Int
dim Vect
min1, Int -> Vect -> Double
forall a v. VecList a v => Int -> v -> a
getElem Int
dim Vect
max1)
v2 :: (Double, Double)
v2@(Double
minv2, Double
maxv2) = (Int -> Vect -> Double
forall a v. VecList a v => Int -> v -> a
getElem Int
dim Vect
min2, Int -> Vect -> Double
forall a v. VecList a v => Int -> v -> a
getElem Int
dim Vect
max2)
in if Double
maxv1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
minv2 Bool -> Bool -> Bool
|| Double
minv1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
maxv2
then Double
0
else let minv1Outside :: Bool
minv1Outside = Double
minv1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
minv2
maxv1Outside :: Bool
maxv1Outside = Double
maxv1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
maxv2
v1Inside :: Bool
v1Inside = Bool -> Bool
not Bool
minv1Outside Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
maxv1Outside
o :: Double
o | Bool
v1Inside = (Double, Double) -> (Double, Double) -> Double
forall {b}. (Ord b, Num b) => (b, b) -> (b, b) -> b
insideOverlap (Double, Double)
v1 (Double, Double)
v2
| Bool
minv1Outside = (Double, Double) -> (Double, Double) -> Double
forall {a} {a} {b}. Num a => (a, a) -> (a, b) -> a
minOutsideOverlap (Double, Double)
v1 (Double, Double)
v2
| Bool
maxv1Outside = (Double, Double) -> (Double, Double) -> Double
forall {a} {b} {a}. Num a => (a, b) -> (a, a) -> a
maxOutsideOverlap (Double, Double)
v1 (Double, Double)
v2
in Double
o
insideOverlap :: (b, b) -> (b, b) -> b
insideOverlap (b
minv1, b
maxv1) (b
minv2, b
maxv2) =
let leftDist :: b
leftDist = b
maxv1 b -> b -> b
forall a. Num a => a -> a -> a
- b
minv2
rightDist :: b
rightDist = b
maxv2 b -> b -> b
forall a. Num a => a -> a -> a
- b
minv1
o :: b
o | b
leftDist b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
rightDist = -b
leftDist
| Bool
otherwise = b
rightDist
in b
o
minOutsideOverlap :: (a, a) -> (a, b) -> a
minOutsideOverlap (a
_, a
maxv1) (a
minv2, b
_) = -(a
maxv1 a -> a -> a
forall a. Num a => a -> a -> a
- a
minv2)
maxOutsideOverlap :: (a, b) -> (a, a) -> a
maxOutsideOverlap (a
minv1, b
_) (a
_, a
maxv2) = a
maxv2 a -> a -> a
forall a. Num a => a -> a -> a
- a
minv1
type Tuple3d = (Double,Double,Double)
fromTuples :: (Tuple3d, Tuple3d) -> Box
fromTuples :: (Tuple3d, Tuple3d) -> Box
fromTuples (Tuple3d
t1, Tuple3d
t2) = Vect -> Vect -> Box
Box (Tuple3d -> Vect
V.fromTuple Tuple3d
t1) (Tuple3d -> Vect
V.fromTuple Tuple3d
t2)
toTuples :: Box -> (Tuple3d, Tuple3d)
toTuples :: Box -> (Tuple3d, Tuple3d)
toTuples (Box Vect
minPt Vect
maxPt) = (Vect -> Tuple3d
V.toTuple Vect
minPt, Vect -> Tuple3d
V.toTuple Vect
maxPt)