HardonCollider: Polygon incompatible with triangulation

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Golan2781
Prole
Posts: 8
Joined: Sat Jan 07, 2012 9:13 pm

HardonCollider: Polygon incompatible with triangulation

Post by Golan2781 »

Hi!
I'm currently trying to get HardonCollider to work properly with collision shapes supplied from an external map source(Tiled). The problem is that many of the shapes created for collision detection in the editor are not reliably compatible with the Kong algorithm used to subdivide the polygon into triangles. While collinear points are discarded when the polygon is first passed to the shape constructor, many of my shapes end up with collinear points during the triangulation process (see the attached sketch) causing the process to fail when trying to convert these invalid triangles to shapes (all three vertices get discarded, creating an empty shape).

Now, the easiest solution would of course be not to use such shapes, but they are simply the most practical solution for the mapping part. I've got some basic ideas to address the issue (discard invalid triangles, discard points with adjacent collinear points, reinitialise the remaining polygon every step) but I've got almost no experience with such algorithms so I'd probably break something or take a very inefficient approach. Any help and tips on how to do this efficiently would be greatly appreciated! Thanks in advance!
Attachments
hcprob.png
hcprob.png (5 KiB) Viewed 3956 times
Last edited by Golan2781 on Sat Jan 07, 2012 10:18 pm, edited 1 time in total.
User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: HardonCollider: Polygon incompatible with triangulation

Post by MarekkPie »

All this talk about Hardon is getting me horny.
gfreak
Prole
Posts: 29
Joined: Wed Jan 04, 2012 5:32 pm

Re: HardonCollider: Polygon incompatible with triangulation

Post by gfreak »

MarekkPie wrote:All this talk about Hardon is getting me horny.
o_O
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: HardonCollider: Polygon incompatible with triangulation

Post by Jasoco »

All this talk about pie is making me hungy.

But this thread isn't about food. It's about a problem. Hopefully someone who actually knows the answer will post.
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: HardonCollider: Polygon incompatible with triangulation

Post by vrld »

This appears to be a bug with HardonCollider. You can fix it by changing the function pointInTriangle() in polygon.lua to:

Code: Select all

local function pointInTriangle(q, p1,p2,p3)
    local v1,v2 = p2 - p1, p3 - p1
    local qp = q - p1
    local dv = v1:cross(v2)
    local l = qp:cross(v2)
    if l < 0 then return false end
    local m = v1:cross(qp)
    if m < 0 then return false end
    return (l+m)/dv < 1
end
I will upload a fixed version soon.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
Golan2781
Prole
Posts: 8
Joined: Sat Jan 07, 2012 9:13 pm

Re: HardonCollider: Polygon incompatible with triangulation

Post by Golan2781 »

Thanks for the reply and help!
With the updated pointInTriangle, it now fails the assert stating "Cannot triangulate polygon (is the polygon intersecting itself?)". I guess it simply ends up with the last three points all in a row, then tries to triangulate these until it fails.

I've fixed it for now by adding a check in the main loop to discard the current point if it is collinear with its directly adjacent points. If I'm not mistaken, this should merely simplify the polygon, not discard any otherwise needed information. This also works with the original pointInTriangle function.

Code: Select all

	local nPoints, skipped = #vertices, 0
	local p = adj[ vertices[2] ]
	while nPoints > 3 do
		-- discard collinear
		if areCollinear(p.l, p.p, p.r) then
			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]
		-- triangulate of vertex is valid
		elseif not concave[p.p] and isEar(p.l, p.p, p.r) then
			triangles[#triangles+1] = Polygon( unpackHelper(p.l, p.p, p.r) )
			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
	triangles[#triangles+1] = Polygon( unpackHelper(p.l, p.p, p.r) )
The polygon I'm operating on is:

Code: Select all

            { x = 0, y = 0 },
            { x = -32, y = 0 },
            { x = -32, y = 96 },
            { x = -320, y = 96 },
            { x = -320, y = 128 },
            { x = -160, y = 128 },
            { x = -160, y = 160 },
            { x = -64, y = 160 },
            { x = -64, y = 288 },
            { x = -32, y = 288 },
            { x = -32, y = 448 },
            { x = 0, y = 448 }
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Amazon [Bot], Bing [Bot] and 4 guests