{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Diagrams.ThreeD.Shapes
(
Skinned(..)
, Ellipsoid(..)
, sphere
, Box(..)
, cube
, Frustum(..)
, frustum
, cone
, cylinder
, CSG(..)
, union
, intersection
, difference
) where
import Control.Lens (review, (^.), _1)
import Data.Typeable
import Data.Semigroup
import Diagrams.Angle
import Diagrams.Core
import Diagrams.Core.Trace
import Diagrams.Points
import Diagrams.Query
import Diagrams.Solve.Polynomial
import Diagrams.ThreeD.Types
import Diagrams.ThreeD.Vector
import Linear.Affine
import Linear.Metric
import Linear.Vector
data Ellipsoid n = Ellipsoid (Transformation V3 n)
deriving Typeable
type instance V (Ellipsoid n) = V3
type instance N (Ellipsoid n) = n
instance Fractional n => Transformable (Ellipsoid n) where
transform :: Transformation (V (Ellipsoid n)) (N (Ellipsoid n))
-> Ellipsoid n -> Ellipsoid n
transform Transformation (V (Ellipsoid n)) (N (Ellipsoid n))
t1 (Ellipsoid Transformation V3 n
t2) = forall n. Transformation V3 n -> Ellipsoid n
Ellipsoid (Transformation (V (Ellipsoid n)) (N (Ellipsoid n))
t1 forall a. Semigroup a => a -> a -> a
<> Transformation V3 n
t2)
instance Fractional n => Renderable (Ellipsoid n) NullBackend where
render :: NullBackend
-> Ellipsoid n
-> Render NullBackend (V (Ellipsoid n)) (N (Ellipsoid n))
render NullBackend
_ Ellipsoid n
_ = forall a. Monoid a => a
mempty
instance OrderedField n => Enveloped (Ellipsoid n) where
getEnvelope :: Ellipsoid n -> Envelope (V (Ellipsoid n)) (N (Ellipsoid n))
getEnvelope (Ellipsoid Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope forall a b. (a -> b) -> a -> b
$ \V3 n
v -> n
1 forall a. Fractional a => a -> a -> a
/ forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm V3 n
v
instance OrderedField n => Traced (Ellipsoid n) where
getTrace :: Ellipsoid n -> Trace (V (Ellipsoid n)) (N (Ellipsoid n))
getTrace (Ellipsoid Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace forall a b. (a -> b) -> a -> b
$ \(P V3 n
p) V3 n
v -> let
a :: n
a = V3 n
v forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 n
v
b :: n
b = n
2 forall a. Num a => a -> a -> a
* (V3 n
p forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 n
v)
c :: n
c = (V3 n
p forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` V3 n
p) forall a. Num a => a -> a -> a
- n
1
in
forall a. Ord a => [a] -> SortedList a
mkSortedList forall a b. (a -> b) -> a -> b
$ forall d. (Floating d, Ord d) => d -> d -> d -> [d]
quadForm n
a n
b n
c
sphere :: Num n => Ellipsoid n
sphere :: forall n. Num n => Ellipsoid n
sphere = forall n. Transformation V3 n -> Ellipsoid n
Ellipsoid forall a. Monoid a => a
mempty
data Box n = Box (Transformation V3 n)
deriving Typeable
type instance V (Box n) = V3
type instance N (Box n) = n
instance Fractional n => Transformable (Box n) where
transform :: Transformation (V (Box n)) (N (Box n)) -> Box n -> Box n
transform Transformation (V (Box n)) (N (Box n))
t1 (Box Transformation V3 n
t2) = forall n. Transformation V3 n -> Box n
Box (Transformation (V (Box n)) (N (Box n))
t1 forall a. Semigroup a => a -> a -> a
<> Transformation V3 n
t2)
instance Fractional n => Renderable (Box n) NullBackend where
render :: NullBackend -> Box n -> Render NullBackend (V (Box n)) (N (Box n))
render NullBackend
_ Box n
_ = forall a. Monoid a => a
mempty
instance OrderedField n => Enveloped (Box n) where
getEnvelope :: Box n -> Envelope (V (Box n)) (N (Box n))
getEnvelope (Box Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope forall a b. (a -> b) -> a -> b
$ \V3 n
v ->
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (forall a b. (a -> b) -> [a] -> [b]
map (V3 n
v forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot`) [V3 n]
corners) forall a. Fractional a => a -> a -> a
/ forall (f :: * -> *) a. (Metric f, Num a) => f a -> a
quadrance V3 n
v where
corners :: [V3 n]
corners = forall n. n -> n -> n -> V3 n
mkR3 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [n
0,n
1] forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [n
0,n
1] forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [n
0,n
1]
instance (Fractional n, Ord n) => Traced (Box n) where
getTrace :: Box n -> Trace (V (Box n)) (N (Box n))
getTrace (Box Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace forall a b. (a -> b) -> a -> b
$ \Point V3 n
p V3 n
v -> let
(n
x0, n
y0, n
z0) = forall n. P3 n -> (n, n, n)
unp3 Point V3 n
p
(n
vx, n
vy, n
vz) = forall n. V3 n -> (n, n, n)
unr3 V3 n
v
intersections :: a -> a -> [a]
intersections a
f a
d = case a
d of
a
0 -> []
a
_ -> [-a
fforall a. Fractional a => a -> a -> a
/a
d, (a
1forall a. Num a => a -> a -> a
-a
f)forall a. Fractional a => a -> a -> a
/a
d]
ts :: [n]
ts = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {a}. (Eq a, Fractional a) => a -> a -> [a]
intersections [n
x0,n
y0,n
z0] [n
vx,n
vy,n
vz]
atT :: n -> Point V3 n
atT n
t = Point V3 n
p forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ (n
tforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^V3 n
v)
range :: P3 a -> Bool
range P3 a
u = forall (t :: * -> *). Foldable t => t Bool -> Bool
and [a
x forall a. Ord a => a -> a -> Bool
>= a
0, a
x forall a. Ord a => a -> a -> Bool
<= a
1, a
y forall a. Ord a => a -> a -> Bool
>= a
0, a
y forall a. Ord a => a -> a -> Bool
<= a
1, a
z forall a. Ord a => a -> a -> Bool
>= a
0, a
z forall a. Ord a => a -> a -> Bool
<= a
1] where
(a
x, a
y, a
z) = forall n. P3 n -> (n, n, n)
unp3 P3 a
u
in
forall a. Ord a => [a] -> SortedList a
mkSortedList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (forall {a}. (Ord a, Num a) => P3 a -> Bool
range forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Point V3 n
atT) forall a b. (a -> b) -> a -> b
$ [n]
ts where
cube :: Num n => Box n
cube :: forall n. Num n => Box n
cube = forall n. Transformation V3 n -> Box n
Box forall a. Monoid a => a
mempty
data Frustum n = Frustum n n (Transformation V3 n)
deriving Typeable
type instance V (Frustum n) = V3
type instance N (Frustum n) = n
instance Fractional n => Transformable (Frustum n) where
transform :: Transformation (V (Frustum n)) (N (Frustum n))
-> Frustum n -> Frustum n
transform Transformation (V (Frustum n)) (N (Frustum n))
t1 (Frustum n
r0 n
r1 Transformation V3 n
t2) = forall n. n -> n -> Transformation V3 n -> Frustum n
Frustum n
r0 n
r1 (Transformation (V (Frustum n)) (N (Frustum n))
t1 forall a. Semigroup a => a -> a -> a
<> Transformation V3 n
t2)
instance Fractional n => Renderable (Frustum n) NullBackend where
render :: NullBackend
-> Frustum n -> Render NullBackend (V (Frustum n)) (N (Frustum n))
render NullBackend
_ Frustum n
_ = forall a. Monoid a => a
mempty
instance (OrderedField n, RealFloat n) => Enveloped (Frustum n) where
getEnvelope :: Frustum n -> Envelope (V (Frustum n)) (N (Frustum n))
getEnvelope (Frustum n
r0 n
r1 Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope forall a b. (a -> b) -> a -> b
$ \V3 n
v ->let
θ :: Angle n
θ = V3 n
v forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) n.
(HasTheta t, RealFloat n) =>
Lens' (t n) (Angle n)
_theta
corners :: [(n, Angle n, n)]
corners = [(n
r1,Angle n
θ,n
1), (-n
r1,Angle n
θ,n
1), (n
r0,Angle n
θ,n
0), (-n
r0,Angle n
θ,n
0)]
in
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
project V3 n
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b (m :: * -> *) t. MonadReader b m => AReview t b -> m t
review forall n. RealFloat n => Iso' (V3 n) (n, Angle n, n)
r3CylindricalIso) forall a b. (a -> b) -> a -> b
$ [(n, Angle n, n)]
corners
instance (RealFloat n, Ord n) => Traced (Frustum n) where
getTrace :: Frustum n -> Trace (V (Frustum n)) (N (Frustum n))
getTrace (Frustum n
r0 n
r1 Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace forall a b. (a -> b) -> a -> b
$ \Point V3 n
p V3 n
v -> let
(n
px, n
py, n
pz) = forall n. P3 n -> (n, n, n)
unp3 Point V3 n
p
(n
vx, n
vy, n
vz) = forall n. V3 n -> (n, n, n)
unr3 V3 n
v
ray :: n -> Point V3 n
ray n
t = Point V3 n
p forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ n
t forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ V3 n
v
dr :: n
dr = n
r1 forall a. Num a => a -> a -> a
- n
r0
a :: n
a = n
vxforall a. Floating a => a -> a -> a
**n
2 forall a. Num a => a -> a -> a
+ n
vyforall a. Floating a => a -> a -> a
**n
2 forall a. Num a => a -> a -> a
- n
vzforall a. Floating a => a -> a -> a
**n
2 forall a. Num a => a -> a -> a
* n
drforall a. Floating a => a -> a -> a
**n
2
b :: n
b = n
2 forall a. Num a => a -> a -> a
* (n
px forall a. Num a => a -> a -> a
* n
vx forall a. Num a => a -> a -> a
+ n
py forall a. Num a => a -> a -> a
* n
vy forall a. Num a => a -> a -> a
- (n
r0forall a. Num a => a -> a -> a
+n
pzforall a. Num a => a -> a -> a
*n
dr) forall a. Num a => a -> a -> a
* n
dr forall a. Num a => a -> a -> a
* n
vz)
c :: n
c = n
pxforall a. Floating a => a -> a -> a
**n
2 forall a. Num a => a -> a -> a
+ n
pyforall a. Floating a => a -> a -> a
**n
2 forall a. Num a => a -> a -> a
- (n
r0 forall a. Num a => a -> a -> a
+ n
drforall a. Num a => a -> a -> a
*n
pz)forall a. Floating a => a -> a -> a
**n
2
zbounds :: n -> Bool
zbounds n
t = n -> Point V3 n
ray n
t forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z forall a. Ord a => a -> a -> Bool
>= n
0
Bool -> Bool -> Bool
&& n -> Point V3 n
ray n
t forall s a. s -> Getting a s a -> a
^. forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z forall a. Ord a => a -> a -> Bool
<= n
1
ends :: [n]
ends = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap n -> [n]
cap [n
0,n
1]
cap :: n -> [n]
cap n
z = [ n
t | n -> Point V3 n
ray n
t forall s a. s -> Getting a s a -> a
^. forall (f :: * -> *) a (g :: * -> *) b.
Lens (Point f a) (Point g b) (f a) (g b)
lensP forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. RealFloat n => Iso' (V3 n) (n, Angle n, n)
r3CylindricalIso forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s t a b. Field1 s t a b => Lens s t a b
_1 forall a. Ord a => a -> a -> Bool
< n
r0 forall a. Num a => a -> a -> a
+ n
z forall a. Num a => a -> a -> a
* n
dr ]
where
t :: n
t = (n
z forall a. Num a => a -> a -> a
- n
pz) forall a. Fractional a => a -> a -> a
/ n
vz
in
forall a. Ord a => [a] -> SortedList a
mkSortedList forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter n -> Bool
zbounds (forall d. (Floating d, Ord d) => d -> d -> d -> [d]
quadForm n
a n
b n
c) forall a. [a] -> [a] -> [a]
++ [n]
ends
frustum :: Num n => n -> n -> Frustum n
frustum :: forall n. Num n => n -> n -> Frustum n
frustum n
r0 n
r1 = forall n. n -> n -> Transformation V3 n -> Frustum n
Frustum n
r0 n
r1 forall a. Monoid a => a
mempty
cone :: Num n => Frustum n
cone :: forall n. Num n => Frustum n
cone = forall n. Num n => n -> n -> Frustum n
frustum n
1 n
0
cylinder :: Num n => Frustum n
cylinder :: forall n. Num n => Frustum n
cylinder = forall n. Num n => n -> n -> Frustum n
frustum n
1 n
1
class Skinned t where
skin :: (Renderable t b, N t ~ n, TypeableFloat n) => t -> QDiagram b V3 n Any
instance (Num n, Ord n) => HasQuery (Ellipsoid n) Any where
getQuery :: Ellipsoid n -> Query (V (Ellipsoid n)) (N (Ellipsoid n)) Any
getQuery (Ellipsoid Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall a b. (a -> b) -> a -> b
$
forall (v :: * -> *) n m. (Point v n -> m) -> Query v n m
Query forall a b. (a -> b) -> a -> b
$ \Point (V (Ellipsoid n)) (N (Ellipsoid n))
v -> Bool -> Any
Any forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. (Metric f, Num a) => f a -> a
quadrance (Point (V (Ellipsoid n)) (N (Ellipsoid n))
v forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin) forall a. Ord a => a -> a -> Bool
<= n
1
instance OrderedField n => Skinned (Ellipsoid n) where
skin :: forall b n.
(Renderable (Ellipsoid n) b, N (Ellipsoid n) ~ n,
TypeableFloat n) =>
Ellipsoid n -> QDiagram b V3 n Any
skin Ellipsoid n
s = forall b (v :: * -> *) n m.
Prim b v n
-> Envelope v n
-> Trace v n
-> SubMap b v n m
-> Query v n m
-> QDiagram b v n m
mkQD (forall p b.
(Transformable p, Typeable p, Renderable p b) =>
p -> Prim b (V p) (N p)
Prim Ellipsoid n
s) (forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Ellipsoid n
s) (forall a. Traced a => a -> Trace (V a) (N a)
getTrace Ellipsoid n
s) forall a. Monoid a => a
mempty (forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Ellipsoid n
s)
instance (Num n, Ord n) => HasQuery (Box n) Any where
getQuery :: Box n -> Query (V (Box n)) (N (Box n)) Any
getQuery (Box Transformation V3 n
tr) = forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n m. (Point v n -> m) -> Query v n m
Query forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. (Ord a, Num a) => P3 a -> Bool
range where
range :: P3 a -> Bool
range P3 a
u = forall (t :: * -> *). Foldable t => t Bool -> Bool
and [a
x forall a. Ord a => a -> a -> Bool
>= a
0, a
x forall a. Ord a => a -> a -> Bool
<= a
1, a
y forall a. Ord a => a -> a -> Bool
>= a
0, a
y forall a. Ord a => a -> a -> Bool
<= a
1, a
z forall a. Ord a => a -> a -> Bool
>= a
0, a
z forall a. Ord a => a -> a -> Bool
<= a
1] where
(a
x, a
y, a
z) = forall n. P3 n -> (n, n, n)
unp3 P3 a
u
instance OrderedField n => Skinned (Box n) where
skin :: forall b n.
(Renderable (Box n) b, N (Box n) ~ n, TypeableFloat n) =>
Box n -> QDiagram b V3 n Any
skin Box n
s = forall b (v :: * -> *) n m.
Prim b v n
-> Envelope v n
-> Trace v n
-> SubMap b v n m
-> Query v n m
-> QDiagram b v n m
mkQD (forall p b.
(Transformable p, Typeable p, Renderable p b) =>
p -> Prim b (V p) (N p)
Prim Box n
s) (forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Box n
s) (forall a. Traced a => a -> Trace (V a) (N a)
getTrace Box n
s) forall a. Monoid a => a
mempty (forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Box n
s)
instance (OrderedField n) => HasQuery (Frustum n) Any where
getQuery :: Frustum n -> Query (V (Frustum n)) (N (Frustum n)) Any
getQuery (Frustum n
r0 n
r1 Transformation V3 n
tr)= forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation V3 n
tr forall a b. (a -> b) -> a -> b
$
forall (v :: * -> *) n m. (Point v n -> m) -> Query v n m
Query forall a b. (a -> b) -> a -> b
$ \Point (V (Frustum n)) (N (Frustum n))
p -> let
z :: n
z = Point (V (Frustum n)) (N (Frustum n))
pforall s a. s -> Getting a s a -> a
^.forall (t :: * -> *) a. R3 t => Lens' (t a) a
_z
r :: n
r = n
r0 forall a. Num a => a -> a -> a
+ (n
r1 forall a. Num a => a -> a -> a
- n
r0)forall a. Num a => a -> a -> a
*n
z
v :: Diff (Point V3) n
v = Point (V (Frustum n)) (N (Frustum n))
p forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
a :: n
a = forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm forall a b. (a -> b) -> a -> b
$ forall {f :: * -> *} {a}.
(Metric f, Fractional a, R3 f) =>
f a -> f a
projectXY Diff (Point V3) n
v
projectXY :: f a -> f a
projectXY f a
u = f a
u forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ forall (v :: * -> *) a.
(Metric v, Fractional a) =>
v a -> v a -> v a
project forall (v :: * -> *) n. (R3 v, Additive v, Num n) => v n
unitZ f a
u
in
Bool -> Any
Any forall a b. (a -> b) -> a -> b
$ n
z forall a. Ord a => a -> a -> Bool
>= n
0 Bool -> Bool -> Bool
&& n
z forall a. Ord a => a -> a -> Bool
<= n
1 Bool -> Bool -> Bool
&& n
a forall a. Ord a => a -> a -> Bool
<= n
r
instance Skinned (Frustum n) where
skin :: forall b n.
(Renderable (Frustum n) b, N (Frustum n) ~ n, TypeableFloat n) =>
Frustum n -> QDiagram b V3 n Any
skin Frustum n
s = forall b (v :: * -> *) n m.
Prim b v n
-> Envelope v n
-> Trace v n
-> SubMap b v n m
-> Query v n m
-> QDiagram b v n m
mkQD (forall p b.
(Transformable p, Typeable p, Renderable p b) =>
p -> Prim b (V p) (N p)
Prim Frustum n
s) (forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Frustum n
s) (forall a. Traced a => a -> Trace (V a) (N a)
getTrace Frustum n
s) forall a. Monoid a => a
mempty (forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Frustum n
s)
data CSG n
= CsgEllipsoid (Ellipsoid n)
| CsgBox (Box n)
| CsgFrustum (Frustum n)
| CsgUnion [CSG n]
| CsgIntersection [CSG n]
| CsgDifference (CSG n) (CSG n)
deriving Typeable
type instance V (CSG n) = V3
type instance N (CSG n) = n
instance Fractional n => Transformable (CSG n) where
transform :: Transformation (V (CSG n)) (N (CSG n)) -> CSG n -> CSG n
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgEllipsoid Ellipsoid n
p) = forall n. Ellipsoid n -> CSG n
CsgEllipsoid forall a b. (a -> b) -> a -> b
$ forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t Ellipsoid n
p
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgBox Box n
p) = forall n. Box n -> CSG n
CsgBox forall a b. (a -> b) -> a -> b
$ forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t Box n
p
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgFrustum Frustum n
p) = forall n. Frustum n -> CSG n
CsgFrustum forall a b. (a -> b) -> a -> b
$ forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t Frustum n
p
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgUnion [CSG n]
ps) = forall n. [CSG n] -> CSG n
CsgUnion forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t) [CSG n]
ps
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgIntersection [CSG n]
ps) = forall n. [CSG n] -> CSG n
CsgIntersection forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t) [CSG n]
ps
transform Transformation (V (CSG n)) (N (CSG n))
t (CsgDifference CSG n
p1 CSG n
p2) = forall n. CSG n -> CSG n -> CSG n
CsgDifference (forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t CSG n
p1) (forall t. Transformable t => Transformation (V t) (N t) -> t -> t
transform Transformation (V (CSG n)) (N (CSG n))
t CSG n
p2)
instance RealFloat n => Enveloped (CSG n) where
getEnvelope :: CSG n -> Envelope (V (CSG n)) (N (CSG n))
getEnvelope (CsgEllipsoid Ellipsoid n
p) = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Ellipsoid n
p
getEnvelope (CsgBox Box n
p) = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Box n
p
getEnvelope (CsgFrustum Frustum n
p) = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope Frustum n
p
getEnvelope (CsgUnion [CSG n]
ps) = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope [CSG n]
ps
getEnvelope (CsgIntersection [CSG n]
ps) = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope [CSG n]
ps
getEnvelope (CsgDifference CSG n
p1 CSG n
p2) = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope CSG n
p1 forall a. Semigroup a => a -> a -> a
<> forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope CSG n
p2
instance (Floating n, Ord n) => HasQuery (CSG n) Any where
getQuery :: CSG n -> Query (V (CSG n)) (N (CSG n)) Any
getQuery (CsgEllipsoid Ellipsoid n
prim) = forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Ellipsoid n
prim
getQuery (CsgBox Box n
prim) = forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Box n
prim
getQuery (CsgFrustum Frustum n
prim) = forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery Frustum n
prim
getQuery (CsgUnion [CSG n]
ps) = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery [CSG n]
ps
getQuery (CsgIntersection [CSG n]
ps) =
Bool -> Any
Any forall b c a. (b -> c) -> (a -> b) -> a -> c
. All -> Bool
getAll forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> All
All forall b c a. (b -> c) -> (a -> b) -> a -> c
. Any -> Bool
getAny) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery) [CSG n]
ps
getQuery (CsgDifference CSG n
p1 CSG n
p2) = Any -> Any -> Any
inOut forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery CSG n
p1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery CSG n
p2 where
inOut :: Any -> Any -> Any
inOut (Any Bool
a) (Any Bool
b) = Bool -> Any
Any forall a b. (a -> b) -> a -> b
$ Bool
a Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
b
instance (RealFloat n, Ord n) => Traced (CSG n) where
getTrace :: CSG n -> Trace (V (CSG n)) (N (CSG n))
getTrace (CsgEllipsoid Ellipsoid n
p) = forall a. Traced a => a -> Trace (V a) (N a)
getTrace Ellipsoid n
p
getTrace (CsgBox Box n
p) = forall a. Traced a => a -> Trace (V a) (N a)
getTrace Box n
p
getTrace (CsgFrustum Frustum n
p) = forall a. Traced a => a -> Trace (V a) (N a)
getTrace Frustum n
p
getTrace (CsgUnion []) = forall a. Monoid a => a
mempty
getTrace (CsgUnion (CSG n
s:[CSG n]
ss)) = forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace Point V3 n -> V3 n -> SortedList n
t where
t :: Point V3 n -> V3 n -> SortedList n
t Point V3 n
pt V3 n
v = forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ CSG n -> n -> Bool
without CSG n
s) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace (forall n. [CSG n] -> CSG n
CsgUnion [CSG n]
ss)) Point V3 n
pt V3 n
v)
forall a. Semigroup a => a -> a -> a
<> forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ CSG n -> n -> Bool
without (forall n. [CSG n] -> CSG n
CsgUnion [CSG n]
ss)) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace CSG n
s) Point V3 n
pt V3 n
v) where
newPt :: n -> Point V3 n
newPt n
dist = Point V3 n
pt forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ V3 n
v forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* n
dist
without :: CSG n -> n -> Bool
without CSG n
prim = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. HasQuery t Any => t -> Point (V t) (N t) -> Bool
inquire CSG n
prim forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Point V3 n
newPt
getTrace (CsgIntersection []) = forall a. Monoid a => a
mempty
getTrace (CsgIntersection (CSG n
s:[CSG n]
ss)) = forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace Point V3 n -> V3 n -> SortedList n
t where
t :: Point V3 n -> V3 n -> SortedList n
t Point V3 n
pt V3 n
v = forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ CSG n -> n -> Bool
within CSG n
s) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace (forall n. [CSG n] -> CSG n
CsgIntersection [CSG n]
ss)) Point V3 n
pt V3 n
v)
forall a. Semigroup a => a -> a -> a
<> forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ CSG n -> n -> Bool
within (forall n. [CSG n] -> CSG n
CsgIntersection [CSG n]
ss)) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace CSG n
s) Point V3 n
pt V3 n
v) where
newPt :: n -> Point V3 n
newPt n
dist = Point V3 n
pt forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ V3 n
v forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* n
dist
within :: CSG n -> n -> Bool
within CSG n
prim = forall t. HasQuery t Any => t -> Point (V t) (N t) -> Bool
inquire CSG n
prim forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Point V3 n
newPt
getTrace (CsgDifference CSG n
s1 CSG n
s2) = forall (v :: * -> *) n.
(Point v n -> v n -> SortedList n) -> Trace v n
mkTrace Point V3 n -> V3 n -> SortedList n
t where
t :: Point V3 n -> V3 n -> SortedList n
t Point V3 n
pt V3 n
v = forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSG n -> n -> Bool
within CSG n
s2) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace CSG n
s1) Point V3 n
pt V3 n
v)
forall a. Semigroup a => a -> a -> a
<> forall b a. Ord b => ([a] -> [b]) -> SortedList a -> SortedList b
onSortedList (forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ CSG n -> n -> Bool
within CSG n
s1) (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace (forall a. Traced a => a -> Trace (V a) (N a)
getTrace CSG n
s2) Point V3 n
pt V3 n
v) where
newPt :: n -> Point V3 n
newPt n
dist = Point V3 n
pt forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ V3 n
v forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* n
dist
within :: CSG n -> n -> Bool
within CSG n
prim = forall t. HasQuery t Any => t -> Point (V t) (N t) -> Bool
inquire CSG n
prim forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Point V3 n
newPt
instance (RealFloat n, Ord n) => Skinned (CSG n) where
skin :: forall b n.
(Renderable (CSG n) b, N (CSG n) ~ n, TypeableFloat n) =>
CSG n -> QDiagram b V3 n Any
skin CSG n
s = forall b (v :: * -> *) n m.
Prim b v n
-> Envelope v n
-> Trace v n
-> SubMap b v n m
-> Query v n m
-> QDiagram b v n m
mkQD (forall p b.
(Transformable p, Typeable p, Renderable p b) =>
p -> Prim b (V p) (N p)
Prim CSG n
s) (forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope CSG n
s) (forall a. Traced a => a -> Trace (V a) (N a)
getTrace CSG n
s) forall a. Monoid a => a
mempty (forall t m. HasQuery t m => t -> Query (V t) (N t) m
getQuery CSG n
s)
class CsgPrim a where
toCsg :: a n -> CSG n
instance CsgPrim Ellipsoid where
toCsg :: forall n. Ellipsoid n -> CSG n
toCsg = forall n. Ellipsoid n -> CSG n
CsgEllipsoid
instance CsgPrim Box where
toCsg :: forall n. Box n -> CSG n
toCsg = forall n. Box n -> CSG n
CsgBox
instance CsgPrim Frustum where
toCsg :: forall n. Frustum n -> CSG n
toCsg = forall n. Frustum n -> CSG n
CsgFrustum
instance CsgPrim CSG where
toCsg :: forall n. CSG n -> CSG n
toCsg = forall a. a -> a
id
union :: (CsgPrim a, CsgPrim b) => a n -> b n -> CSG n
union :: forall (a :: * -> *) (b :: * -> *) n.
(CsgPrim a, CsgPrim b) =>
a n -> b n -> CSG n
union a n
a b n
b = forall n. [CSG n] -> CSG n
CsgUnion [forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg a n
a, forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg b n
b]
intersection :: (CsgPrim a, CsgPrim b) => a n -> b n -> CSG n
intersection :: forall (a :: * -> *) (b :: * -> *) n.
(CsgPrim a, CsgPrim b) =>
a n -> b n -> CSG n
intersection a n
a b n
b = forall n. [CSG n] -> CSG n
CsgIntersection [forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg a n
a, forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg b n
b]
difference :: (CsgPrim a, CsgPrim b) => a n -> b n -> CSG n
difference :: forall (a :: * -> *) (b :: * -> *) n.
(CsgPrim a, CsgPrim b) =>
a n -> b n -> CSG n
difference a n
a b n
b = forall n. CSG n -> CSG n -> CSG n
CsgDifference (forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg a n
a) (forall (a :: * -> *) n. CsgPrim a => a n -> CSG n
toCsg b n
b)