module HGeometry.Polygon.Simple.Class
( SimplePolygon_(..)
) where
import Control.Lens
import Data.Default
import qualified Data.Foldable as F
import Data.Foldable1
import Data.Kind (Constraint)
import HGeometry.Ext
import HGeometry.Point.Class
import HGeometry.Polygon.Class
import HGeometry.Vector
class ( Polygon_ simplePolygon point r
, VertexIx simplePolygon ~ Int
, Point_ point 2 r
) => SimplePolygon_ simplePolygon point r where
uncheckedFromCCWPoints :: Foldable1 f => f point -> simplePolygon
type ConstructableSimplePolygon simplePolygon point r :: Constraint
type ConstructableSimplePolygon simplePolygon point r = (Eq r, Num r)
fromPoints :: ( Foldable f
, ConstructableSimplePolygon simplePolygon point r
)
=> f point -> Maybe simplePolygon
centroid :: (Fractional r, ConstructablePoint_ point' 2 r) => simplePolygon -> point'
centroid simplePolygon
poly = Vector 2 r -> point'
forall point (d :: Nat) r.
ConstructablePoint_ point d r =>
Vector d r -> point
fromVector (Vector 2 r -> point') -> Vector 2 r -> point'
forall a b. (a -> b) -> a -> b
$ [Vector 2 r] -> Vector 2 r
sum' [Vector 2 r]
xs Vector 2 r -> r -> Vector 2 r
forall vector (d :: Nat) r.
(Vector_ vector d r, Fractional r) =>
vector -> r -> vector
^/ (r
3 r -> r -> r
forall a. Num a => a -> a -> a
* simplePolygon -> r
forall r simplePolygon point.
(Num r, HasOuterBoundary simplePolygon, Point_ point 2 r,
Vertex simplePolygon ~ point) =>
simplePolygon -> r
signedArea2X simplePolygon
poly)
where
xs :: [Vector 2 r]
xs = [ (point
ppoint -> Getting (Vector 2 r) point (Vector 2 r) -> Vector 2 r
forall s a. s -> Getting a s a -> a
^.Getting (Vector 2 r) point (Vector 2 r)
forall (d :: Nat) r s.
(Dimension point ~ d, NumType point ~ r, Dimension point ~ d,
NumType point ~ s) =>
Lens point point (Vector d r) (Vector d s)
forall point point' (d :: Nat) r s.
(HasVector point point', Dimension point ~ d, NumType point ~ r,
Dimension point' ~ d, NumType point' ~ s) =>
Lens point point' (Vector d r) (Vector d s)
Lens point point (Vector 2 r) (Vector 2 r)
vector Vector 2 r -> Vector 2 r -> Vector 2 r
forall r vector (d :: Nat).
(Num r, Additive_ vector d r) =>
vector -> vector -> vector
^+^ point
qpoint -> Getting (Vector 2 r) point (Vector 2 r) -> Vector 2 r
forall s a. s -> Getting a s a -> a
^.Getting (Vector 2 r) point (Vector 2 r)
forall (d :: Nat) r s.
(Dimension point ~ d, NumType point ~ r, Dimension point ~ d,
NumType point ~ s) =>
Lens point point (Vector d r) (Vector d s)
forall point point' (d :: Nat) r s.
(HasVector point point', Dimension point ~ d, NumType point ~ r,
Dimension point' ~ d, NumType point' ~ s) =>
Lens point point' (Vector d r) (Vector d s)
Lens point point (Vector 2 r) (Vector 2 r)
vector) Vector 2 r -> r -> Vector 2 r
forall r vector (d :: Nat).
(Num r, Vector_ vector d r) =>
vector -> r -> vector
^* (point
ppoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord r -> r -> r
forall a. Num a => a -> a -> a
* point
qpoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
yCoord r -> r -> r
forall a. Num a => a -> a -> a
- point
qpoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord r -> r -> r
forall a. Num a => a -> a -> a
* point
ppoint -> Getting r point r -> r
forall s a. s -> Getting a s a -> a
^.Getting r point r
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
yCoord)
| (point
p,point
q) <- simplePolygon
poly simplePolygon
-> Getting (Endo [(point, point)]) simplePolygon (point, point)
-> [(point, point)]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^..Getting (Endo [(point, point)]) simplePolygon (point, point)
((Vertex simplePolygon, Vertex simplePolygon)
-> Const
(Endo [(point, point)])
(Vertex simplePolygon, Vertex simplePolygon))
-> simplePolygon -> Const (Endo [(point, point)]) simplePolygon
forall polygon.
HasOuterBoundary polygon =>
IndexedFold1
(VertexIx polygon, VertexIx polygon)
polygon
(Vertex polygon, Vertex polygon)
IndexedFold1
(VertexIx simplePolygon, VertexIx simplePolygon)
simplePolygon
(Vertex simplePolygon, Vertex simplePolygon)
outerBoundaryEdges ]
sum' :: [Vector 2 r] -> Vector 2 r
sum' = (Vector 2 r -> Vector 2 r -> Vector 2 r)
-> Vector 2 r -> [Vector 2 r] -> Vector 2 r
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' Vector 2 r -> Vector 2 r -> Vector 2 r
forall r vector (d :: Nat).
(Num r, Additive_ vector d r) =>
vector -> vector -> vector
(^+^) Vector 2 r
forall r vector (d :: Nat). (Num r, Additive_ vector d r) => vector
zero
instance ( SimplePolygon_ simplePolygon point r
, Default extra
)
=> SimplePolygon_ (simplePolygon :+ extra) point r where
uncheckedFromCCWPoints :: forall (f :: * -> *).
Foldable1 f =>
f point -> simplePolygon :+ extra
uncheckedFromCCWPoints = (simplePolygon -> extra -> simplePolygon :+ extra
forall core extra. core -> extra -> core :+ extra
:+ extra
forall a. Default a => a
def) (simplePolygon -> simplePolygon :+ extra)
-> (f point -> simplePolygon) -> f point -> simplePolygon :+ extra
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f point -> simplePolygon
forall simplePolygon point r (f :: * -> *).
(SimplePolygon_ simplePolygon point r, Foldable1 f) =>
f point -> simplePolygon
forall (f :: * -> *). Foldable1 f => f point -> simplePolygon
uncheckedFromCCWPoints
type ConstructableSimplePolygon (simplePolygon :+ extra) point r =
(ConstructableSimplePolygon simplePolygon point r, Default extra)
fromPoints :: forall (f :: * -> *).
(Foldable f,
ConstructableSimplePolygon (simplePolygon :+ extra) point r) =>
f point -> Maybe (simplePolygon :+ extra)
fromPoints = (simplePolygon -> simplePolygon :+ extra)
-> Maybe simplePolygon -> Maybe (simplePolygon :+ extra)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (simplePolygon -> extra -> simplePolygon :+ extra
forall core extra. core -> extra -> core :+ extra
:+ extra
forall a. Default a => a
def) (Maybe simplePolygon -> Maybe (simplePolygon :+ extra))
-> (f point -> Maybe simplePolygon)
-> f point
-> Maybe (simplePolygon :+ extra)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f point -> Maybe simplePolygon
forall simplePolygon point r (f :: * -> *).
(SimplePolygon_ simplePolygon point r, Foldable f,
ConstructableSimplePolygon simplePolygon point r) =>
f point -> Maybe simplePolygon
forall (f :: * -> *).
(Foldable f, ConstructableSimplePolygon simplePolygon point r) =>
f point -> Maybe simplePolygon
fromPoints