{- ORMOLU_DISABLE -}
-- Implicit CAD. Copyright (C) 2011, Christopher Olah (chris@colah.ca)
-- Copyright 2014 2015 2016, Julia Longtin (julial@turinglace.com)
-- Copyright 2015 2016, Mike MacHenry (mike.machenry@gmail.com)
-- Released under the GNU AGPLV3+, see LICENSE

module Graphics.Implicit.ObjectUtil.GetBox3 (getBox3) where

import Prelude(uncurry, pure, Bool(False), Either (Left, Right), (==), max, (/), (-), (+), fmap, unzip, ($), (<$>), (.), minimum, maximum, min, (>), (*), (<), abs, either, const, otherwise, take, fst, snd)

import Graphics.Implicit.Definitions
    ( Fastℕ,
      fromFastℕ,
      ExtrudeMScale(C2, C1),
      SymbolicObj3(Shared3, Cube, Sphere, Cylinder, Rotate3, Transform3, Extrude, ExtrudeOnEdgeOf, ExtrudeM, RotateExtrude),
      Box3,
      ,
      fromFastℕtoℝ,
      toScaleFn )

import Graphics.Implicit.ObjectUtil.GetBox2 (getBox2, getBox2R)

import Graphics.Implicit.ObjectUtil.GetBoxShared (corners, pointsBox, getBoxShared)

import Linear (V2(V2), V3(V3))
import qualified Linear

-- FIXME: many variables are being ignored here. no rounding for intersect, or difference.. etc.

-- Get a Box3 around the given object.
getBox3 :: SymbolicObj3 -> Box3
-- Primitives
getBox3 :: SymbolicObj3 -> Box3
getBox3 (Shared3 SharedObj SymbolicObj3 V3 ℝ
obj) = SharedObj SymbolicObj3 V3 ℝ -> Box3
forall obj (f :: * -> *) a.
(Object obj f a, VectorStuff (f a), ComponentWiseMultable (f a),
 Fractional a, Metric f) =>
SharedObj obj f a -> (f a, f a)
getBoxShared SharedObj SymbolicObj3 V3 ℝ
obj
getBox3 (Cube ℝ3
size) = (ℝ -> ℝ3
forall (f :: * -> *) a. Applicative f => a -> f a
pure 0, ℝ3
size)
getBox3 (Sphere r) = (ℝ -> ℝ3
forall (f :: * -> *) a. Applicative f => a -> f a
pure (-r), ℝ -> ℝ3
forall (f :: * -> *) a. Applicative f => a -> f a
pure r)
getBox3 (Cylinder h r1 r2) = (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (-r) (-r) 0, ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 r r h ) where r :: ℝ
r = ℝ -> ℝ -> ℝ
forall a. Ord a => a -> a -> a
max r1 r2
-- (Rounded) CSG
-- Simple transforms
getBox3 (Rotate3 Quaternion ℝ
q SymbolicObj3
symbObj) =
    let box :: Box3
box = SymbolicObj3 -> Box3
getBox3 SymbolicObj3
symbObj
     in [ℝ3] -> Box3
forall (f :: * -> *) a.
(Applicative f, Num a, VectorStuff (f a)) =>
[f a] -> (f a, f a)
pointsBox ([ℝ3] -> Box3) -> [ℝ3] -> Box3
forall a b. (a -> b) -> a -> b
$ Quaternion ℝ -> ℝ3 -> ℝ3
forall a.
(Conjugate a, RealFloat a) =>
Quaternion a -> V3 a -> V3 a
Linear.rotate Quaternion ℝ
q (ℝ3 -> ℝ3) -> [ℝ3] -> [ℝ3]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Box3 -> [ℝ3]
forall vec. VectorStuff vec => (vec, vec) -> [vec]
corners Box3
box
getBox3 (Transform3 M44 ℝ
m SymbolicObj3
symbObj) =
    let box :: Box3
box = SymbolicObj3 -> Box3
getBox3 SymbolicObj3
symbObj
     in [ℝ3] -> Box3
forall (f :: * -> *) a.
(Applicative f, Num a, VectorStuff (f a)) =>
[f a] -> (f a, f a)
pointsBox ([ℝ3] -> Box3) -> [ℝ3] -> Box3
forall a b. (a -> b) -> a -> b
$ V4 ℝ -> ℝ3
forall a. Fractional a => V4 a -> V3 a
Linear.normalizePoint (V4 ℝ -> ℝ3) -> (ℝ3 -> V4 ℝ) -> ℝ3 -> ℝ3
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (M44 ℝ
m M44 ℝ -> V4 ℝ -> V4 ℝ
forall (m :: * -> *) (r :: * -> *) a.
(Functor m, Foldable r, Additive r, Num a) =>
m (r a) -> r a -> m a
Linear.!*) (V4 ℝ -> V4 ℝ) -> (ℝ3 -> V4 ℝ) -> ℝ3 -> V4 ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ3 -> V4 ℝ
forall a. Num a => V3 a -> V4 a
Linear.point (ℝ3 -> ℝ3) -> [ℝ3] -> [ℝ3]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Box3 -> [ℝ3]
forall vec. VectorStuff vec => (vec, vec) -> [vec]
corners Box3
box
-- Misc
-- 2D Based
getBox3 (Extrude SymbolicObj2
symbObj h) = (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 x1 y1 0, ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 x2 y2 h)
    where
        (V2 x1 y1, V2 x2 y2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj
getBox3 (ExtrudeOnEdgeOf SymbolicObj2
symbObj1 SymbolicObj2
symbObj2) =
    let
        (V2 ax1 ay1, V2 ax2 ay2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj1
        (V2 bx1 by1, V2 bx2 by2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj2
    in
        (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (bx1ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ax1) (by1ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ax1) ay1, ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (bx2ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ax2) (by2ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ax2) ay2)
-- FIXME: magic numbers: 0.2 and 11.
-- FIXME: this may use an approximation, based on sampling functions. generate a warning if the approximation part of this function is used.
-- FIXME: re-implement the expression system, so this can recieve a function, and determine class (constant, linear)... and implement better forms of this function.
getBox3 (ExtrudeM Either ℝ (ℝ -> ℝ)
twist ExtrudeMScale
scale Either (V2 ℝ) (ℝ -> V2 ℝ)
translate SymbolicObj2
symbObj Either ℝ (V2 ℝ -> ℝ)
height) =
    let
        (V2 x1 y1, V2 x2 y2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj
        (dx, dy) = (x2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- x1, y2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- y1)

        samples :: Fastℕ
        samples :: Fastℕ
samples = Fastℕ
11
        range :: [Fastℕ]
        range :: [Fastℕ]
range = [Fastℕ
0, Fastℕ
1 .. (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)]
        ([ℝ]
xrange, [ℝ]
yrange) = ( (Fastℕ -> ℝ) -> [Fastℕ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((\s -> x1ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+sℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*dxℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/Fastℕ -> ℝ
fromFastℕtoℝ (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)) (ℝ -> ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fastℕ -> ℝ
fromFastℕtoℝ) [Fastℕ]
range, (Fastℕ -> ℝ) -> [Fastℕ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((\s -> y1ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+sℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*dyℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/Fastℕ -> ℝ
fromFastℕtoℝ (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)) (ℝ -> ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fastℕ -> ℝ
fromFastℕtoℝ) [Fastℕ]
range)

        hfuzz :: 
        hfuzz :: ℝ
hfuzz = 0.2
        h :: ℝ
h = case Either ℝ (V2 ℝ -> ℝ)
height of
              Left hval -> hval
              Right V2 ℝ -> ℝ
hfun -> hmax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ hfuzzℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*(hmaxℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
-hmin)
                where
                    hs :: [ℝ]
hs = [V2 ℝ -> ℝ
hfun (V2 ℝ -> ℝ) -> V2 ℝ -> ℝ
forall a b. (a -> b) -> a -> b
$ ℝ -> ℝ -> V2 ℝ
forall a. a -> a -> V2 a
V2 x y | x <- [ℝ]
xrange, y <- [ℝ]
yrange]
                    (hmin, hmax) = ([ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [ℝ]
hs, [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [ℝ]
hs)
        hrange :: [ℝ]
hrange = (Fastℕ -> ℝ) -> [Fastℕ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/ Fastℕ -> ℝ
fromFastℕtoℝ (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)) (ℝ -> ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (hℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*) (ℝ -> ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fastℕ -> ℝ
fromFastℕtoℝ) [Fastℕ]
range

        (twistXmin, twistYmin, twistXmax, twistYmax) =
          let
            both :: (t -> b) -> (t, t) -> (b, b)
both t -> b
f (t
a, t
b) = (t -> b
f t
a, t -> b
f t
b)
            (V2 scalex' scaley') = case ExtrudeMScale
scale of
              C1 s -> ℝ -> ℝ -> V2 ℝ
forall a. a -> a -> V2 a
V2 s s
              C2 V2 ℝ
s -> V2 ℝ
s
              ExtrudeMScale
s -> (ℝ, ℝ) -> V2 ℝ
forall a. (a, a) -> V2 a
pack ((ℝ, ℝ) -> V2 ℝ) -> (ℝ, ℝ) -> V2 ℝ
forall a b. (a -> b) -> a -> b
$ ([ℝ] -> ℝ) -> ([ℝ], [ℝ]) -> (ℝ, ℝ)
forall t b. (t -> b) -> (t, t) -> (b, b)
both [ℝ] -> ℝ
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])
unzip ([(ℝ, ℝ)] -> (ℝ, ℝ)) -> [(ℝ, ℝ)] -> (ℝ, ℝ)
forall a b. (a -> b) -> a -> b
$ (V2 ℝ -> (ℝ, ℝ)) -> [V2 ℝ] -> [(ℝ, ℝ)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap V2 ℝ -> (ℝ, ℝ)
forall a. V2 a -> (a, a)
unpack ([V2 ℝ] -> [(ℝ, ℝ)]) -> [V2 ℝ] -> [(ℝ, ℝ)]
forall a b. (a -> b) -> a -> b
$ (ℝ -> ℝ) -> V2 ℝ -> V2 ℝ
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ℝ -> ℝ
forall a. Num a => a -> a
abs (V2 ℝ -> V2 ℝ) -> (ℝ -> V2 ℝ) -> ℝ -> V2 ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtrudeMScale -> ℝ -> V2 ℝ
toScaleFn ExtrudeMScale
s (ℝ -> V2 ℝ) -> [ℝ] -> [V2 ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ℝ]
hrange
            smin :: a -> a -> a
smin a
s a
v = a -> a -> a
forall a. Ord a => a -> a -> a
min a
v (a
s a -> a -> a
forall a. Num a => a -> a -> a
* a
v)
            smax :: a -> a -> a
smax a
s a
v = a -> a -> a
forall a. Ord a => a -> a -> a
max a
v (a
s a -> a -> a
forall a. Num a => a -> a -> a
* a
v)
            -- FIXME: assumes minimums are negative, and maximums are positive.
            scaleEach :: (V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)
scaleEach (V2 d1 d2, V2 d3 d4) = (scalex' ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* d1, scaley' ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* d2, scalex' ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* d3, scaley' ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* d4)
          in case Either ℝ (ℝ -> ℝ)
twist of
            Left twval -> if twval ℝ -> ℝ -> Bool
forall a. Eq a => a -> a -> Bool
== 0
                          then (ℝ -> ℝ -> ℝ
forall a. (Ord a, Num a) => a -> a -> a
smin scalex' x1, ℝ -> ℝ -> ℝ
forall a. (Ord a, Num a) => a -> a -> a
smin scaley' y1, ℝ -> ℝ -> ℝ
forall a. (Ord a, Num a) => a -> a -> a
smax scalex' x2, ℝ -> ℝ -> ℝ
forall a. (Ord a, Num a) => a -> a -> a
smax scaley' y2)
                          else (V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)
scaleEach ((V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)) -> (V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)
forall a b. (a -> b) -> a -> b
$ SymbolicObj2 -> ℝ -> (V2 ℝ, V2 ℝ)
getBox2R SymbolicObj2
symbObj twval
            Right ℝ -> ℝ
_  -> (V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)
scaleEach ((V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)) -> (V2 ℝ, V2 ℝ) -> (ℝ, ℝ, ℝ, ℝ)
forall a b. (a -> b) -> a -> b
$ SymbolicObj2 -> ℝ -> (V2 ℝ, V2 ℝ)
getBox2R SymbolicObj2
symbObj 360 -- we can't range functions yet, so assume a full circle.

        (tminx, tmaxx, tminy, tmaxy) =
          let
            tvalsx :: ( -> V2 ) -> []
            tvalsx :: (ℝ -> V2 ℝ) -> [ℝ]
tvalsx ℝ -> V2 ℝ
tfun = (ℝ -> ℝ) -> [ℝ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ℝ, ℝ) -> ℝ
forall a b. (a, b) -> a
fst ((ℝ, ℝ) -> ℝ) -> (ℝ -> (ℝ, ℝ)) -> ℝ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V2 ℝ -> (ℝ, ℝ)
forall a. V2 a -> (a, a)
unpack (V2 ℝ -> (ℝ, ℝ)) -> (ℝ -> V2 ℝ) -> ℝ -> (ℝ, ℝ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> V2 ℝ
tfun) [ℝ]
hrange
            tvalsy :: ( -> V2 ) -> []
            tvalsy :: (ℝ -> V2 ℝ) -> [ℝ]
tvalsy ℝ -> V2 ℝ
tfun = (ℝ -> ℝ) -> [ℝ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ℝ, ℝ) -> ℝ
forall a b. (a, b) -> b
snd ((ℝ, ℝ) -> ℝ) -> (ℝ -> (ℝ, ℝ)) -> ℝ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V2 ℝ -> (ℝ, ℝ)
forall a. V2 a -> (a, a)
unpack (V2 ℝ -> (ℝ, ℝ)) -> (ℝ -> V2 ℝ) -> ℝ -> (ℝ, ℝ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> V2 ℝ
tfun) [ℝ]
hrange
          in case Either (V2 ℝ) (ℝ -> V2 ℝ)
translate of
            Left  (V2 tvalx tvaly) -> (tvalx, tvalx, tvaly, tvaly)
            Right ℝ -> V2 ℝ
tfun -> ( [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum ([ℝ] -> ℝ) -> [ℝ] -> ℝ
forall a b. (a -> b) -> a -> b
$ (ℝ -> V2 ℝ) -> [ℝ]
tvalsx ℝ -> V2 ℝ
tfun
                          , [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([ℝ] -> ℝ) -> [ℝ] -> ℝ
forall a b. (a -> b) -> a -> b
$ (ℝ -> V2 ℝ) -> [ℝ]
tvalsx ℝ -> V2 ℝ
tfun
                          , [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum ([ℝ] -> ℝ) -> [ℝ] -> ℝ
forall a b. (a -> b) -> a -> b
$ (ℝ -> V2 ℝ) -> [ℝ]
tvalsy ℝ -> V2 ℝ
tfun
                          , [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([ℝ] -> ℝ) -> [ℝ] -> ℝ
forall a b. (a -> b) -> a -> b
$ (ℝ -> V2 ℝ) -> [ℝ]
tvalsy ℝ -> V2 ℝ
tfun
                          )
    in
        (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (twistXmin ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ tminx) (twistYmin ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ tminy) 0, ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (twistXmax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ tmaxx) (twistYmax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ tmaxy) h)
-- Note: Assumes x2 is always greater than x1.
-- FIXME: Insert the above assumption as an assertion in the type system?
getBox3 (RotateExtrude _ (Left (V2 xshift yshift)) Either ℝ (ℝ -> ℝ)
_ SymbolicObj2
symbObj) =
    let
        (V2 _ y1, V2 x2 y2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj
        r :: ℝ
r = ℝ -> ℝ -> ℝ
forall a. Ord a => a -> a -> a
max x2 (x2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ xshift)
    in
        (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (-r) (-r) (ℝ -> ℝ3) -> ℝ -> ℝ3
forall a b. (a -> b) -> a -> b
$ ℝ -> ℝ -> ℝ
forall a. Ord a => a -> a -> a
min y1 (y1 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ yshift), ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 r r (ℝ -> ℝ3) -> ℝ -> ℝ3
forall a b. (a -> b) -> a -> b
$ ℝ -> ℝ -> ℝ
forall a. Ord a => a -> a -> a
max y2 (y2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ yshift))
-- FIXME: magic numbers: 0.1, 1.1, and 11.
-- FIXME: this may use an approximation, based on sampling functions. generate a warning if the approximation part of this function is used.
-- FIXME: re-implement the expression system, so this can recieve a function, and determine class (constant, linear)... and implement better forms of this function.
getBox3 (RotateExtrude rot (Right ℝ -> V2 ℝ
f) Either ℝ (ℝ -> ℝ)
rotate SymbolicObj2
symbObj) =
    let
        samples :: Fastℕ
        samples :: Fastℕ
samples = Fastℕ
11
        xfuzz :: 
        xfuzz :: ℝ
xfuzz = 1.1
        yfuzz :: 
        yfuzz :: ℝ
yfuzz=0.1
        range :: [Fastℕ]
        range :: [Fastℕ]
range = [Fastℕ
0, Fastℕ
1 .. (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)]
        step :: ℝ
step = rotℝ -> ℝ -> ℝ
forall a. Fractional a => a -> a -> a
/Fastℕ -> ℝ
fromFastℕtoℝ (Fastℕ
samplesFastℕ -> Fastℕ -> Fastℕ
forall a. Num a => a -> a -> a
-Fastℕ
1)
        (V2 x1 y1, V2 x2 y2) = SymbolicObj2 -> (V2 ℝ, V2 ℝ)
getBox2 SymbolicObj2
symbObj
        ([ℝ]
xrange, [ℝ]
yrange) = [(ℝ, ℝ)] -> ([ℝ], [ℝ])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(ℝ, ℝ)] -> ([ℝ], [ℝ])) -> [(ℝ, ℝ)] -> ([ℝ], [ℝ])
forall a b. (a -> b) -> a -> b
$ (V2 ℝ -> (ℝ, ℝ)) -> [V2 ℝ] -> [(ℝ, ℝ)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap V2 ℝ -> (ℝ, ℝ)
forall a. V2 a -> (a, a)
unpack ([V2 ℝ] -> [(ℝ, ℝ)]) -> [V2 ℝ] -> [(ℝ, ℝ)]
forall a b. (a -> b) -> a -> b
$ Int -> [V2 ℝ] -> [V2 ℝ]
forall a. Int -> [a] -> [a]
take (Fastℕ -> Int
forall n. FastN n => Fastℕ -> n
fromFastℕ Fastℕ
samples) ([V2 ℝ] -> [V2 ℝ]) -> [V2 ℝ] -> [V2 ℝ]
forall a b. (a -> b) -> a -> b
$ (Fastℕ -> V2 ℝ) -> [Fastℕ] -> [V2 ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ℝ -> V2 ℝ
f (ℝ -> V2 ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> V2 ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (stepℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
*) (ℝ -> ℝ) -> (Fastℕ -> ℝ) -> Fastℕ -> ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fastℕ -> ℝ
fromFastℕtoℝ) [Fastℕ]
range
        xmax :: ℝ
xmax = [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [ℝ]
xrange
        ymax :: ℝ
ymax = [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [ℝ]
yrange
        ymin :: ℝ
ymin = [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [ℝ]
yrange
        xmax' :: ℝ
xmax' | xmax ℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
> 0 = xmax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* xfuzz
              | xmax ℝ -> ℝ -> Bool
forall a. Ord a => a -> a -> Bool
< - x1 = 0
              | Bool
otherwise = xmax
        ymax' :: ℝ
ymax' = ymax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ yfuzz ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* (ymax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- ymin)
        ymin' :: ℝ
ymin' = ymin ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- yfuzz ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
* (ymax ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
- ymin)
        (r, _, _) = if (ℝ -> Bool) -> ((ℝ -> ℝ) -> Bool) -> Either ℝ (ℝ -> ℝ) -> Bool
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (ℝ -> ℝ -> Bool
forall a. Eq a => a -> a -> Bool
==0) (Bool -> (ℝ -> ℝ) -> Bool
forall a b. a -> b -> a
const Bool
False) Either ℝ (ℝ -> ℝ)
rotate
            then let
                s :: ℝ
s = [ℝ] -> ℝ
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([ℝ] -> ℝ) -> [ℝ] -> ℝ
forall a b. (a -> b) -> a -> b
$ (ℝ -> ℝ) -> [ℝ] -> [ℝ]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ℝ -> ℝ
forall a. Num a => a -> a
abs [x2, y1, y2]
            in (s ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ xmax', s ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymin', y2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymax')
            else (x2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ xmax', y1 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymin', y2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymax')
    in
        (ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 (-r) (-r) (ℝ -> ℝ3) -> ℝ -> ℝ3
forall a b. (a -> b) -> a -> b
$ y1 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymin', ℝ -> ℝ -> ℝ -> ℝ3
forall a. a -> a -> a -> V3 a
V3 r  r  (ℝ -> ℝ3) -> ℝ -> ℝ3
forall a b. (a -> b) -> a -> b
$ y2 ℝ -> ℝ -> ℝ
forall a. Num a => a -> a -> a
+ ymax')

unpack :: V2 a -> (a, a)
unpack :: V2 a -> (a, a)
unpack (V2 a
a a
b) = (a
a, a
b)

pack :: (a, a) -> V2 a
pack :: (a, a) -> V2 a
pack = (a -> a -> V2 a) -> (a, a) -> V2 a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> a -> V2 a
forall a. a -> a -> V2 a
V2