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

-- For the definition of centroid.
{-# LANGUAGE FlexibleContexts #-}

-- Functions to make meshes/polylines finer.

module Graphics.Implicit.Export.Util (normTriangle, normVertex, centroid) where

import Prelude(Num, Applicative, Foldable, pure, (+), Fractional, (/), (-), realToFrac, length)

import Graphics.Implicit.Definitions (, ℝ3, Obj3, Triangle(Triangle), NormedTriangle(NormedTriangle))
import Linear ((*^), (^/), normalize, V3(V3))
import Data.List (foldl')

-- Change the default for bare numbers in this file.
default ()

-- FIXME: magic numbers.
normTriangle ::  -> Obj3 -> Triangle -> NormedTriangle
normTriangle :: ℝ -> Obj3 -> Triangle -> NormedTriangle
normTriangle res Obj3
obj (Triangle (ℝ3
a,ℝ3
b,ℝ3
c)) =
    ((ℝ3, ℝ3), (ℝ3, ℝ3), (ℝ3, ℝ3)) -> NormedTriangle
NormedTriangle ((ℝ3
a, ℝ3 -> ℝ3
normify ℝ3
a'), (ℝ3
b, ℝ3 -> ℝ3
normify ℝ3
b'), (ℝ3
c, ℝ3 -> ℝ3
normify ℝ3
c'))
        where
            normify :: ℝ3 -> ℝ3
normify = ℝ -> Obj3 -> ℝ3 -> ℝ3
normVertex res Obj3
obj
            a' :: ℝ3
a' = (ℝ3
a forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
b forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
c) forall (f :: * -> *) a.
(Functor f, Fractional a) =>
f a -> a -> f a
^/ 1.02
            b' :: ℝ3
b' = (ℝ3
b forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
a forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
c) forall (f :: * -> *) a.
(Functor f, Fractional a) =>
f a -> a -> f a
^/ 1.02
            c' :: ℝ3
c' = (ℝ3
c forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
b forall a. Num a => a -> a -> a
+ rforall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
a) forall (f :: * -> *) a.
(Functor f, Fractional a) =>
f a -> a -> f a
^/ 1.02
            r :: 
            r :: ℝ
r = 0.01

-- FIXME: magic numbers.
normVertex ::  -> Obj3 -> ℝ3 -> ℝ3
normVertex :: ℝ -> Obj3 -> ℝ3 -> ℝ3
normVertex res Obj3
obj ℝ3
p =
    let
        -- D_vf(p) = ( f(p) - f(p+v) ) /|v|
        -- but we'll actually scale v by res, so then |v| = res
        -- and that f is obj
        -- and is fixed at p
        -- so actually: d v = ...
        d :: ℝ3 -> 
        d :: Obj3
d ℝ3
v = ( Obj3
obj (ℝ3
p forall a. Num a => a -> a -> a
+ (resforall a. Fractional a => a -> a -> a
/100)forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
v) forall a. Num a => a -> a -> a
- Obj3
obj (ℝ3
p forall a. Num a => a -> a -> a
- (resforall a. Fractional a => a -> a -> a
/100)forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ℝ3
v) ) forall a. Fractional a => a -> a -> a
/ (resforall a. Fractional a => a -> a -> a
/50)
        dx :: ℝ
dx = Obj3
d (forall a. a -> a -> a -> V3 a
V3 1 0 0)
        dy :: ℝ
dy = Obj3
d (forall a. a -> a -> a -> V3 a
V3 0 1 0)
        dz :: ℝ
dz = Obj3
d (forall a. a -> a -> a -> V3 a
V3 0 0 1)
    in forall a (f :: * -> *).
(Floating a, Metric f, Epsilon a) =>
f a -> f a
normalize (forall a. a -> a -> a -> V3 a
V3 dx dy dz)

-- Get a centroid of a series of points.
centroid :: (Fractional a, Foldable t, Applicative f, Num (f a)) => t (f a) -> f a
centroid :: forall a (t :: * -> *) (f :: * -> *).
(Fractional a, Foldable t, Applicative f, Num (f a)) =>
t (f a) -> f a
centroid t (f a)
pts = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall a. Num a => a -> a -> a
(+) (forall (f :: * -> *) a. Applicative f => a -> f a
pure a
0) t (f a)
pts forall (f :: * -> *) a.
(Functor f, Fractional a) =>
f a -> a -> f a
^/ forall a b. (Real a, Fractional b) => a -> b
realToFrac (forall (t :: * -> *) a. Foldable t => t a -> Int
length t (f a)
pts)
{-# INLINABLE centroid #-}