--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.Polygon
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- A polygon and some basic functions to interact with them.
--
--------------------------------------------------------------------------------
module HGeometry.Polygon
  ( module HGeometry.Polygon.Class
  , asTriangle
  , area2X
  , area

  , module HGeometry.Polygon.Simple
  , module HGeometry.Polygon.Convex
  ) where

import Control.Lens hiding (holes)
import HGeometry.Point.Class
import HGeometry.Polygon.Class
import HGeometry.Polygon.Simple
import HGeometry.Polygon.Convex
import HGeometry.Triangle

--------------------------------------------------------------------------------

-- | Try to convert the polygon into a triangle (whose vertices are given in CCW order).
asTriangle    :: Polygon_ polygon point r => polygon -> Maybe (Triangle point)
asTriangle :: forall polygon point r.
Polygon_ polygon point r =>
polygon -> Maybe (Triangle point)
asTriangle polygon
pg = case polygon
pgpolygon -> Getting (Endo [point]) polygon point -> [point]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^..Getting (Endo [point]) polygon point
(Vertex polygon -> Const (Endo [point]) (Vertex polygon))
-> polygon -> Const (Endo [point]) polygon
forall graph graph'.
HasVertices graph graph' =>
IndexedTraversal1
  (VertexIx graph) graph graph' (Vertex graph) (Vertex graph')
IndexedTraversal1
  (VertexIx polygon)
  polygon
  polygon
  (Vertex polygon)
  (Vertex polygon)
vertices of
                  [point
u,point
v,point
w] -> Triangle point -> Maybe (Triangle point)
forall a. a -> Maybe a
Just (Triangle point -> Maybe (Triangle point))
-> Triangle point -> Maybe (Triangle point)
forall a b. (a -> b) -> a -> b
$ point -> point -> point -> Triangle point
forall point. point -> point -> point -> Triangle point
Triangle point
u point
v point
w
                  [point]
_       -> Maybe (Triangle point)
forall a. Maybe a
Nothing

-- | The area of a polygon
--
-- running time: \(O(n)\)
area :: ( Polygon_ polygon point r
        , SimplePolygon_ (Hole polygon) point r
        , Fractional r) => polygon -> r
area :: forall polygon point r.
(Polygon_ polygon point r, SimplePolygon_ (Hole polygon) point r,
 Fractional r) =>
polygon -> r
area = (r -> r -> r
forall a. Fractional a => a -> a -> a
/r
2) (r -> r) -> (polygon -> r) -> polygon -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. polygon -> r
forall polygon point r.
(Polygon_ polygon point r, Num r, Point_ point 2 r,
 SimplePolygon_ (Hole polygon) point r) =>
polygon -> r
area2X

-- | Computes the double area of a polygon
area2X      :: ( Polygon_ polygon point r
               , Num r
               , Point_ point 2 r
               , SimplePolygon_ (Hole polygon) point r
               ) => polygon -> r
area2X :: forall polygon point r.
(Polygon_ polygon point r, Num r, Point_ point 2 r,
 SimplePolygon_ (Hole polygon) point r) =>
polygon -> r
area2X polygon
poly = polygon -> r
forall r simplePolygon point.
(Num r, HasOuterBoundary simplePolygon, Point_ point 2 r,
 Vertex simplePolygon ~ point) =>
simplePolygon -> r
signedArea2X polygon
poly r -> r -> r
forall a. Num a => a -> a -> a
- Getting (Endo (Endo r)) polygon r -> polygon -> r
forall a s. Num a => Getting (Endo (Endo a)) s a -> s -> a
sumOf ((SimplePolygonF (HoleF polygon) point
 -> Const (Endo (Endo r)) (SimplePolygonF (HoleF polygon) point))
-> polygon -> Const (Endo (Endo r)) polygon
(Hole polygon -> Const (Endo (Endo r)) (Hole polygon))
-> polygon -> Const (Endo (Endo r)) polygon
forall polygon.
HasHoles polygon =>
IndexedTraversal' (HoleIx polygon) polygon (Hole polygon)
IndexedTraversal' (HoleIx polygon) polygon (Hole polygon)
holes((SimplePolygonF (HoleF polygon) point
  -> Const (Endo (Endo r)) (SimplePolygonF (HoleF polygon) point))
 -> polygon -> Const (Endo (Endo r)) polygon)
-> ((r -> Const (Endo (Endo r)) r)
    -> SimplePolygonF (HoleF polygon) point
    -> Const (Endo (Endo r)) (SimplePolygonF (HoleF polygon) point))
-> Getting (Endo (Endo r)) polygon r
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(SimplePolygonF (HoleF polygon) point -> r)
-> (r -> Const (Endo (Endo r)) r)
-> SimplePolygonF (HoleF polygon) point
-> Const (Endo (Endo r)) (SimplePolygonF (HoleF polygon) point)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to SimplePolygonF (HoleF polygon) point -> r
forall r simplePolygon point.
(Num r, HasOuterBoundary simplePolygon, Point_ point 2 r,
 Vertex simplePolygon ~ point) =>
simplePolygon -> r
signedArea2X) polygon
poly