module Codec.Picture.Geometry
( FPoint2D
, Point2D
, centroid
, clockwise
, closed
) where
import Data.Foldable (foldl')
import Data.List (sortBy)
import Numeric.Extras (fmod)
type Point2D = (Int, Int)
type FPoint2D = (Double, Double)
centroid ::
[Point2D]
-> Maybe FPoint2D
centroid [] = Nothing
centroid ps =
let (totalX, totalY, n') = foldl' (\(accX, accY, n) (x, y) -> (accX + x, accY + y, n + 1)) (0, 0, 0 :: Int) ps
n'' = fromIntegral n'
in Just (fromIntegral totalX / n'', fromIntegral totalY / n'')
closed ::
[Point2D]
-> [Point2D]
closed [] = []
closed ps@(p : _ ) = ps ++ [p]
clockwise ::
[Point2D]
-> [Point2D]
clockwise ps =
case centroid ps of
Just (cx, cy) -> sortBy (\(ax, ay) (bx, by) ->
let a1 = angle (fromIntegral ax) (fromIntegral ay) cx cy
a2 = angle (fromIntegral bx) (fromIntegral by) cx cy
in compare a2 a1) ps
Nothing -> []
angle :: Double -> Double -> Double -> Double -> Double
angle x y cx cy = fmod (degrees (atan2 (x - cx) (y - cy)) + 360) 360
degrees :: Double -> Double
degrees rad = rad * pi / 180