GeomProcess
The GeMA Geometry Process Plugin
GeomProcess

Convex hull

geom.getConvexHull(coordAccessor, inclusive)
Description: Get the 2D convex hull of all the nodes in a given mesh. The implementation is based on https://www.algorithmist.com/index.php/Monotone_Chain_Convex_Hull.cpp algorithm.
Parameters: coordAccessor An accessor for the mesh node coordinates (see mesh:nodeCoordAccessor()).
inclusive When set to true, the returned list will contain the potential colinear nodes. In this case a home-made and not-so-fast algorithm is used.
Returns: The returning list of CCW ordered node ids defining the convex hull.

Point in convex polygon

geom.pointInConvexPolygon(pointCoord, coordAccessor, nodeIds)
Description: Check if a 2D point is inside or outside the convex polygon delimited by a set of mesh nodes.
Parameters: pointCoord A lua table with the coordinates of the point.
coordAccessor An accessor for the mesh node coordinates (see mesh:nodeCoordAccessor()).
nodeIds The list of CCW ordered node ids defining the convex polygon.
Important: no check is done in regard to the convexity of the input polygon!
Returns: true if the point is inside, or false otherwise.

Example using the two previous functions:

-- Check that all the nodes of a mesh are inside the mesh convex hull
local mesh = modelData:mesh('mesh')
local crdAc = mesh:nodeCoordAccessor()
local convexHull = geom.getConvexHull(crdAc)
for i=1, mesh:numNodes() do
local point = crdAc:value(i)
assert(geom.pointInConvexPolygon(point, crdAc, convexHull))
end

Delaunay triangulation

geom.delaunayTriangulation(coordAccessor)
Description: Compute the 2D delaunay triangulation of all the nodes in a given mesh. The implementation uses the https://github.com/mapbox/delaunator code.
Parameters: coordAccessor An accessor for the mesh node coordinates (see mesh:nodeCoordAccessor()).
Returns: Three equal-size lua tables which size is equal to the number of triangles in the computed triangulation. The returned tables respectively store the first, second and third node id of each triangle.

Example:

-- Build a triangle mesh starting from a grid-based set of points
-- and its corresponding delaunay triangulation
-- define the grid corners
local xmin, xmax = -10, 10 -- left / right
local ymin, ymax = -10, 10 -- bottom / top
-- number of grid subdivisions in each direction
local ni, nj = 10, 10
-- compute point coordinates as part of a regular grid
local v = {}
for i=0, ni do
local x = xmin + (i/ni) * (xmax-xmin)
for j=0, nj do
local y = ymin + (j/nj) * (ymax-ymin)
table.insert(v, Vector({x, y}))
end
end
assert(#v == (ni+1)*(nj+1))
-- empty mesh!
local mesh = modelData:mesh('mesh')
local crdAcc = mesh:nodeCoordAccessor()
-- add nodes to mesh and set its coordinates
mesh:addNodes(#v)
for i=1, #v do
crdAcc:setValue(i, v[i])
end
-- process delaunay triangulation
local t1, t2, t3 = geom.delaunayTriangulation(crdAcc)
-- add triangles to mesh and set its nodes incidence
mesh:addCells({tri3 = #t1})
for i=1, mesh:numCells() do
local cell = mesh:cell(i)
cell:setNodes({t1[i], t2[i], t3[i]}, mesh)
end
-- print mesh geometry
mesh:printValues()

GeMA project main page