module Graphics.Implicit.Export.Render.RefineSegs (refine) where
import Prelude((<), (/), (<>), (*), ($), (&&), (-), (+), (.), (>), abs, (<=))
import Graphics.Implicit.Definitions (ℝ, ℝ2, Polyline(Polyline), minℝ, Fastℕ, Obj2)
import Graphics.Implicit.Export.Util (centroid)
import Linear ( Metric(norm, dot), V2(V2), normalize, (^*) )
default (Fastℕ, ℝ)
refine :: ℝ -> Obj2 -> Polyline -> Polyline
refine :: ℝ -> Obj2 -> Polyline -> Polyline
refine ℝ
res Obj2
obj = ℝ -> Polyline -> Polyline
simplify ℝ
res forall b c a. (b -> c) -> (a -> b) -> a -> c
. ℝ -> Obj2 -> Polyline -> Polyline
detail' ℝ
res Obj2
obj
detail' :: ℝ -> (ℝ2 -> ℝ) -> Polyline -> Polyline
detail' :: ℝ -> Obj2 -> Polyline -> Polyline
detail' ℝ
res Obj2
obj (Polyline [p1 :: ℝ2
p1@(V2 ℝ
x1 ℝ
y1), p2 :: ℝ2
p2@(V2 ℝ
x2 ℝ
y2)])
| (ℝ
x2forall a. Num a => a -> a -> a
-ℝ
x1)forall a. Num a => a -> a -> a
*(ℝ
x2forall a. Num a => a -> a -> a
-ℝ
x1) forall a. Num a => a -> a -> a
+ (ℝ
y2forall a. Num a => a -> a -> a
-ℝ
y1)forall a. Num a => a -> a -> a
*(ℝ
y2forall a. Num a => a -> a -> a
-ℝ
y1) forall a. Ord a => a -> a -> Bool
> ℝ
resforall a. Num a => a -> a -> a
*ℝ
resforall a. Fractional a => a -> a -> a
/ℝ
200 = Fastℕ -> ℝ -> Obj2 -> Polyline -> Polyline
detail Fastℕ
0 ℝ
res Obj2
obj forall a b. (a -> b) -> a -> b
$ [ℝ2] -> Polyline
Polyline [ℝ2
p1,ℝ2
p2]
detail' ℝ
_ Obj2
_ Polyline
a = Polyline
a
detail :: Fastℕ -> ℝ -> (ℝ2 -> ℝ) -> Polyline -> Polyline
detail :: Fastℕ -> ℝ -> Obj2 -> Polyline -> Polyline
detail Fastℕ
n ℝ
res Obj2
obj (Polyline [ℝ2
p1, ℝ2
p2]) | Fastℕ
n forall a. Ord a => a -> a -> Bool
< Fastℕ
2 =
let
mid :: ℝ2
mid = forall a (t :: * -> *) (f :: * -> *).
(Fractional a, Foldable t, Applicative f, Num (f a)) =>
t (f a) -> f a
centroid [ℝ2
p1,ℝ2
p2]
midval :: ℝ
midval = Obj2
obj ℝ2
mid
in if forall a. Num a => a -> a
abs ℝ
midval forall a. Ord a => a -> a -> Bool
< ℝ
res forall a. Fractional a => a -> a -> a
/ ℝ
40
then [ℝ2] -> Polyline
Polyline [ℝ2
p1, ℝ2
p2]
else
let
normal :: ℝ2
normal = (\(V2 ℝ
a ℝ
b) -> forall a. a -> a -> V2 a
V2 ℝ
b (-ℝ
a)) forall a b. (a -> b) -> a -> b
$ forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize (ℝ2
p2 forall a. Num a => a -> a -> a
- ℝ2
p1)
derivN :: ℝ
derivN = -(Obj2
obj (ℝ2
mid forall a. Num a => a -> a -> a
- (ℝ2
normal forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* (ℝ
midvalforall a. Fractional a => a -> a -> a
/ℝ
2))) forall a. Num a => a -> a -> a
- ℝ
midval) forall a. Num a => a -> a -> a
* (ℝ
2forall a. Fractional a => a -> a -> a
/ℝ
midval)
in
if forall a. Num a => a -> a
abs ℝ
derivN forall a. Ord a => a -> a -> Bool
> ℝ
0.5 Bool -> Bool -> Bool
&& forall a. Num a => a -> a
abs ℝ
derivN forall a. Ord a => a -> a -> Bool
< ℝ
2 Bool -> Bool -> Bool
&& forall a. Num a => a -> a
abs (ℝ
midvalforall a. Fractional a => a -> a -> a
/ℝ
derivN) forall a. Ord a => a -> a -> Bool
< ℝ
3forall a. Num a => a -> a -> a
*ℝ
res
then
let
mid' :: ℝ2
mid' = ℝ2
mid forall a. Num a => a -> a -> a
- (ℝ2
normal forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^* (ℝ
midval forall a. Fractional a => a -> a -> a
/ ℝ
derivN))
in
Polyline -> Polyline -> Polyline
addPolylines (Fastℕ -> ℝ -> Obj2 -> Polyline -> Polyline
detail (Fastℕ
nforall a. Num a => a -> a -> a
+Fastℕ
1) ℝ
res Obj2
obj ([ℝ2] -> Polyline
Polyline [ℝ2
p1, ℝ2
mid'])) (Fastℕ -> ℝ -> Obj2 -> Polyline -> Polyline
detail (Fastℕ
nforall a. Num a => a -> a -> a
+Fastℕ
1) ℝ
res Obj2
obj ( [ℝ2] -> Polyline
Polyline [ℝ2
mid', ℝ2
p2] ))
else [ℝ2] -> Polyline
Polyline [ℝ2
p1, ℝ2
p2]
detail Fastℕ
_ ℝ
_ Obj2
_ Polyline
x = Polyline
x
simplify :: ℝ -> Polyline -> Polyline
simplify :: ℝ -> Polyline -> Polyline
simplify ℝ
_ = Polyline -> Polyline
simplify1
simplify1 :: Polyline -> Polyline
simplify1 :: Polyline -> Polyline
simplify1 (Polyline (ℝ2
a:ℝ2
b:ℝ2
c:[ℝ2]
xs)) =
if forall a. Num a => a -> a
abs ( ((ℝ2
b forall a. Num a => a -> a -> a
- ℝ2
a) forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` (ℝ2
c forall a. Num a => a -> a -> a
- ℝ2
a)) forall a. Num a => a -> a -> a
- forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm (ℝ2
b forall a. Num a => a -> a -> a
- ℝ2
a) forall a. Num a => a -> a -> a
* forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm (ℝ2
c forall a. Num a => a -> a -> a
- ℝ2
a) ) forall a. Ord a => a -> a -> Bool
<= ℝ
minℝ
then Polyline -> Polyline
simplify1 ([ℝ2] -> Polyline
Polyline (ℝ2
aforall a. a -> [a] -> [a]
:ℝ2
cforall a. a -> [a] -> [a]
:[ℝ2]
xs))
else Polyline -> Polyline -> Polyline
addPolylines ([ℝ2] -> Polyline
Polyline [ℝ2
a]) (Polyline -> Polyline
simplify1 ([ℝ2] -> Polyline
Polyline (ℝ2
bforall a. a -> [a] -> [a]
:ℝ2
cforall a. a -> [a] -> [a]
:[ℝ2]
xs)))
simplify1 Polyline
a = Polyline
a
addPolylines :: Polyline -> Polyline -> Polyline
addPolylines :: Polyline -> Polyline -> Polyline
addPolylines (Polyline [ℝ2]
as) (Polyline [ℝ2]
bs) = [ℝ2] -> Polyline
Polyline ([ℝ2]
as forall a. Semigroup a => a -> a -> a
<> [ℝ2]
bs)