63 lines
1.6 KiB
Haskell
63 lines
1.6 KiB
Haskell
{-# OPTIONS_HADDOCK ignore-exports #-}
|
|
|
|
module Algebra.Polygon where
|
|
|
|
import Algebra.Vector
|
|
import Data.Maybe
|
|
import Diagrams.TwoD.Types
|
|
import MyPrelude
|
|
|
|
|
|
-- |Split a polygon by a given segment which must be vertices of the
|
|
-- polygon (returns empty array otherwise).
|
|
splitPoly :: [P2 Double]
|
|
-> (P2 Double, P2 Double)
|
|
-> [[P2 Double]]
|
|
splitPoly pts (a, b)
|
|
| elem a pts && elem b pts =
|
|
[b : takeWhile (/= b) shiftedPoly, a : dropWhile (/= b) shiftedPoly]
|
|
| otherwise = [[]]
|
|
where
|
|
shiftedPoly = shiftM' a pts
|
|
|
|
|
|
-- |Get all edges of a polygon.
|
|
polySegments :: [P2 Double] -> [(P2 Double, P2 Double)]
|
|
polySegments p@(x':_:_:_) = go p ++ [(last p, x')]
|
|
where
|
|
go (x:y:xs) = (x, y) : go (y:xs)
|
|
go _ = []
|
|
polySegments _ = []
|
|
|
|
|
|
-- |Check whether the given segment is inside the polygon.
|
|
-- This doesn't check for segments that are completely outside
|
|
-- of the polygon yet.
|
|
isInsidePoly :: [P2 Double] -> (P2 Double, P2 Double) -> Bool
|
|
isInsidePoly pts seg =
|
|
null
|
|
. catMaybes
|
|
. fmap (intersectSeg seg)
|
|
$ polySegments pts
|
|
|
|
|
|
-- |Check whether two points are adjacent vertices of a polygon.
|
|
adjacent :: P2 Double -> P2 Double -> [P2 Double] -> Bool
|
|
adjacent u v = any (\x -> x == (u, v) || x == (v, u)) . polySegments
|
|
|
|
|
|
-- |Check whether the polygon is a triangle polygon.
|
|
isTrianglePoly :: [P2 Double] -> Bool
|
|
isTrianglePoly [_, _, _] = True
|
|
isTrianglePoly _ = False
|
|
|
|
|
|
-- |Get all triangle polygons.
|
|
triangleOnly :: [[P2 Double]] -> [[P2 Double]]
|
|
triangleOnly = filter isTrianglePoly
|
|
|
|
|
|
-- |Get all non-triangle polygons.
|
|
nonTriangleOnly :: [[P2 Double]] -> [[P2 Double]]
|
|
nonTriangleOnly = filter (not . isTrianglePoly)
|