mirror of
https://github.com/vrld/HC.git
synced 2024-11-18 12:54:23 +00:00
Use love.math.triangulate instead of own implementation
This commit is contained in:
parent
cabee18c81
commit
bf35186904
66
polygon.lua
66
polygon.lua
@ -263,71 +263,7 @@ end
|
|||||||
|
|
||||||
-- triangulation by the method of kong
|
-- triangulation by the method of kong
|
||||||
function Polygon:triangulate()
|
function Polygon:triangulate()
|
||||||
if #self.vertices == 3 then return {self:clone()} end
|
return love.math.triangulate(self.vertices)
|
||||||
local triangles = {} -- list of triangles to be returned
|
|
||||||
local concave = {} -- list of concave edges
|
|
||||||
local adj = {} -- vertex adjacencies
|
|
||||||
local vertices = self.vertices
|
|
||||||
|
|
||||||
-- retrieve adjacencies as the rest will be easier to implement
|
|
||||||
for i,p in ipairs(vertices) do
|
|
||||||
local l = (i == 1) and vertices[#vertices] or vertices[i-1]
|
|
||||||
local r = (i == #vertices) and vertices[1] or vertices[i+1]
|
|
||||||
adj[p] = {p = p, l = l, r = r} -- point, left and right neighbor
|
|
||||||
-- test if vertex is a concave edge
|
|
||||||
if not ccw(l,p,r) then concave[p] = p end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- and ear is an edge of the polygon that contains no other
|
|
||||||
-- vertex of the polygon
|
|
||||||
local function isEar(p1,p2,p3)
|
|
||||||
if not ccw(p1,p2,p3) then return false end
|
|
||||||
for q,_ in pairs(concave) do
|
|
||||||
if q ~= p1 and q ~= p2 and q ~= p3 and pointInTriangle(q, p1,p2,p3) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- main loop
|
|
||||||
local nPoints, skipped = #vertices, 0
|
|
||||||
local p = adj[ vertices[2] ]
|
|
||||||
while nPoints > 3 do
|
|
||||||
if not concave[p.p] and isEar(p.l, p.p, p.r) then
|
|
||||||
-- polygon may be a 'collinear triangle', i.e.
|
|
||||||
-- all three points are on a line. In that case
|
|
||||||
-- the polygon constructor throws an error.
|
|
||||||
if not areCollinear(p.l, p.p, p.r) then
|
|
||||||
triangles[#triangles+1] = newPolygon(p.l.x,p.l.y, p.p.x,p.p.y, p.r.x,p.r.y)
|
|
||||||
skipped = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if concave[p.l] and ccw(adj[p.l].l, p.l, p.r) then
|
|
||||||
concave[p.l] = nil
|
|
||||||
end
|
|
||||||
if concave[p.r] and ccw(p.l, p.r, adj[p.r].r) then
|
|
||||||
concave[p.r] = nil
|
|
||||||
end
|
|
||||||
-- remove point from list
|
|
||||||
adj[p.p] = nil
|
|
||||||
adj[p.l].r = p.r
|
|
||||||
adj[p.r].l = p.l
|
|
||||||
nPoints = nPoints - 1
|
|
||||||
skipped = 0
|
|
||||||
p = adj[p.l]
|
|
||||||
else
|
|
||||||
p = adj[p.r]
|
|
||||||
skipped = skipped + 1
|
|
||||||
assert(skipped <= nPoints, "Cannot triangulate polygon (is the polygon intersecting itself?)")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not areCollinear(p.l, p.p, p.r) then
|
|
||||||
triangles[#triangles+1] = newPolygon(p.l.x,p.l.y, p.p.x,p.p.y, p.r.x,p.r.y)
|
|
||||||
end
|
|
||||||
|
|
||||||
return triangles
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- return merged polygon if possible or nil otherwise
|
-- return merged polygon if possible or nil otherwise
|
||||||
|
Loading…
Reference in New Issue
Block a user