diff --git a/src/earcut.js b/src/earcut.js index 2cfd60d..afcefb6 100644 --- a/src/earcut.js +++ b/src/earcut.js @@ -336,26 +336,35 @@ function findHoleBridge(hole, outerNode) { tanMin = Infinity, tan; - p = m.next; + p = m; - while (p !== stop) { + do { if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { tan = Math.abs(hy - p.y) / (hx - p.x); // tangential - if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { + if (locallyInside(p, hole) && + (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { m = p; tanMin = tan; } } p = p.next; - } + } while (p !== stop); return m; } +// whether sector in vertex m contains sector in vertex p in the same coordinates +function sectorContainsSector(m, p) { + return ( + (area(m.prev, m, p.prev) < 0 || area(p.prev, m, m.next) < 0) && + (area(m.prev, m, p.next) < 0 || area(p.next, m, m.next) < 0) + ); +} + // interlink polygon nodes in z-order function indexCurve(start, minX, minY, invSize) { var p = start; diff --git a/test/expected.json b/test/expected.json index 7a07940..9d16cd8 100644 --- a/test/expected.json +++ b/test/expected.json @@ -34,7 +34,8 @@ "issue107": 0, "issue111": 19, "boxy": 57, - "collinear-diagonal": 14 + "collinear-diagonal": 14, + "issue119": 18 }, "errors": { "dude": 2e-15, diff --git a/test/fixtures/issue119.json b/test/fixtures/issue119.json new file mode 100644 index 0000000..0791037 --- /dev/null +++ b/test/fixtures/issue119.json @@ -0,0 +1,7 @@ +[ +[[2,12],[2,20],[25,20],[25,12]], +[[7,18],[7,15],[5,15]], +[[19,18],[19,17],[17,17]], +[[19,17],[21,17],[19,16]], +[[7,15],[9,15],[7,13]] +]