module Geometry.HCDT.Delaunay
  ( delaunay,
    cdelaunay
  )
where

import           Foreign.Marshal.Alloc       (free, mallocBytes)
import           Foreign.Marshal.Array       (pokeArray)
import           Foreign.Storable            (peek, sizeOf)
import           Geometry.HCDT.Triangulation
import           Geometry.HCDT.Types         (Triangulation, Vertex, ConstrainedTriangulation, Edge)

-- | Unconstrained 2d Delaunay triangulation.
delaunay :: [Vertex] -> IO Triangulation
delaunay :: [Vertex] -> IO Triangulation
delaunay [Vertex]
vertices = do
  let nvertices :: Int
nvertices = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vertex]
vertices
  Ptr CVertex
verticesPtr <- forall a. Int -> IO (Ptr a)
mallocBytes (Int
nvertices forall a. Num a => a -> a -> a
* forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CVertex))
  [CVertex]
cvertices <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Vertex -> IO CVertex
vertexToCVertex [Vertex]
vertices
  forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CVertex
verticesPtr [CVertex]
cvertices
  Ptr CTriangulation
ctriangulationPtr <- Ptr CVertex -> CSize -> IO (Ptr CTriangulation)
c_delaunay Ptr CVertex
verticesPtr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nvertices)
  CTriangulation
ctriangulation <- forall a. Storable a => Ptr a -> IO a
peek Ptr CTriangulation
ctriangulationPtr 
  forall a. Ptr a -> IO ()
free Ptr CVertex
verticesPtr
  forall a. Ptr a -> IO ()
free Ptr CTriangulation
ctriangulationPtr
  CTriangulation -> IO Triangulation
cTriangulationToTriangulation CTriangulation
ctriangulation

-- | Constrained 2d Delaunay triangulation.
cdelaunay :: [Vertex] -> [Edge] -> IO ConstrainedTriangulation
cdelaunay :: [Vertex] -> [Edge] -> IO ConstrainedTriangulation
cdelaunay [Vertex]
vertices [Edge]
edges = do
  let nvertices :: Int
nvertices = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vertex]
vertices
  Ptr CVertex
verticesPtr <- forall a. Int -> IO (Ptr a)
mallocBytes (Int
nvertices forall a. Num a => a -> a -> a
* forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CVertex))
  [CVertex]
cvertices <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Vertex -> IO CVertex
vertexToCVertex [Vertex]
vertices
  forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CVertex
verticesPtr [CVertex]
cvertices
  let nedges :: Int
nedges = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Edge]
edges
  Ptr CEdge
edgesPtr <- forall a. Int -> IO (Ptr a)
mallocBytes (Int
nedges forall a. Num a => a -> a -> a
* forall a. Storable a => a -> Int
sizeOf (forall a. HasCallStack => a
undefined :: CEdge))
  [CEdge]
cedges <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Edge -> IO CEdge
edgeToCEdge [Edge]
edges
  forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr CEdge
edgesPtr [CEdge]
cedges
  Ptr CCTriangulation
cctriangulationPtr <- Ptr CVertex
-> CSize -> Ptr CEdge -> CSize -> IO (Ptr CCTriangulation)
c_cdelaunay Ptr CVertex
verticesPtr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nvertices) Ptr CEdge
edgesPtr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nedges)
  CCTriangulation
cctriangulation <- forall a. Storable a => Ptr a -> IO a
peek Ptr CCTriangulation
cctriangulationPtr 
  forall a. Ptr a -> IO ()
free Ptr CVertex
verticesPtr
  forall a. Ptr a -> IO ()
free Ptr CEdge
edgesPtr
  forall a. Ptr a -> IO ()
free Ptr CCTriangulation
cctriangulationPtr
  CCTriangulation -> IO ConstrainedTriangulation
cCTriangulationToConstrainedTriangulation CCTriangulation
cctriangulation