From 38bccee237318b9f920b0e8a07190ac19bdc539d Mon Sep 17 00:00:00 2001 From: Michael Barry Date: Wed, 18 Dec 2024 04:13:44 -0500 Subject: [PATCH] Fix edge cases when inner rings are touching (#177) * fix all except touching-holes4 * other * fix benchmarks * viz tweaks, test rotations, and fix other bugs * rm diffs * rm extra diff * perf tweak * comment * perf tweaks --- bench/basic.js | 2 +- bench/bench.js | 2 +- src/earcut.js | 57 ++++--- test/expected.json | 27 +++- test/fixtures/touching-holes2.json | 1 + test/fixtures/touching-holes3.json | 1 + test/fixtures/touching-holes4.json | 1 + test/fixtures/touching-holes5.json | 1 + test/fixtures/touching-holes6.json | 1 + test/test.js | 47 ++++-- viz/viz.js | 247 +++++++++++++++-------------- 11 files changed, 224 insertions(+), 163 deletions(-) create mode 100644 test/fixtures/touching-holes2.json create mode 100644 test/fixtures/touching-holes3.json create mode 100644 test/fixtures/touching-holes4.json create mode 100644 test/fixtures/touching-holes5.json create mode 100644 test/fixtures/touching-holes6.json diff --git a/bench/basic.js b/bench/basic.js index 98deb80..8ba5f37 100644 --- a/bench/basic.js +++ b/bench/basic.js @@ -1,4 +1,4 @@ -import {earcut, flatten} from '../src/earcut.js'; +import earcut, {flatten} from '../src/earcut.js'; import {readFileSync} from 'fs'; const data = JSON.parse(readFileSync(new URL('../test/fixtures/building.json', import.meta.url))); diff --git a/bench/bench.js b/bench/bench.js index f9f0afa..f7a6bd4 100644 --- a/bench/bench.js +++ b/bench/bench.js @@ -1,4 +1,4 @@ -import {earcut, flatten} from '../src/earcut.js'; +import earcut, {flatten} from '../src/earcut.js'; import Benchmark from 'benchmark'; import {readFileSync} from 'fs'; diff --git a/src/earcut.js b/src/earcut.js index b03397e..ff75641 100644 --- a/src/earcut.js +++ b/src/earcut.js @@ -140,16 +140,16 @@ function isEar(ear) { // now make sure we don't have other points inside the potential ear const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; - // triangle bbox; min & max are calculated like this for speed - const x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), - y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), - x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), - y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); + // triangle bbox + const x0 = Math.min(ax, bx, cx), + y0 = Math.min(ay, by, cy), + x1 = Math.max(ax, bx, cx), + y1 = Math.max(ay, by, cy); let p = c.next; while (p !== a) { if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && - pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && + pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.next; } @@ -166,11 +166,11 @@ function isEarHashed(ear, minX, minY, invSize) { const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; - // triangle bbox; min & max are calculated like this for speed - const x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), - y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), - x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), - y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); + // triangle bbox + const x0 = Math.min(ax, bx, cx), + y0 = Math.min(ay, by, cy), + x1 = Math.max(ax, bx, cx), + y1 = Math.max(ay, by, cy); // z-order range for the current triangle bbox; const minZ = zOrder(x0, y0, minX, minY, invSize), @@ -182,25 +182,25 @@ function isEarHashed(ear, minX, minY, invSize) { // look for points inside the triangle in both directions while (p && p.z >= minZ && n && n.z <= maxZ) { if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && - pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.prevZ; if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && - pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } // look for remaining points in decreasing z-order while (p && p.z >= minZ) { if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && - pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; p = p.prevZ; } // look for remaining points in increasing z-order while (n && n.z <= maxZ) { if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && - pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } @@ -268,7 +268,7 @@ function eliminateHoles(data, holeIndices, outerNode, dim) { queue.push(getLeftmost(list)); } - queue.sort(compareX); + queue.sort(compareXYSlope); // process holes from left to right for (let i = 0; i < queue.length; i++) { @@ -278,8 +278,19 @@ function eliminateHoles(data, holeIndices, outerNode, dim) { return outerNode; } -function compareX(a, b) { - return a.x - b.x; +function compareXYSlope(a, b) { + let result = a.x - b.x; + // when the left-most point of 2 holes meet at a vertex, sort the holes counterclockwise so that when we find + // the bridge to the outer shell is always the point that they meet at. + if (result === 0) { + result = a.y - b.y; + if (result === 0) { + const aSlope = (a.next.y - a.y) / (a.next.x - a.x); + const bSlope = (b.next.y - b.y) / (b.next.x - b.x); + result = aSlope - bSlope; + } + } + return result; } // find a bridge between vertices that connects hole with an outer ring and and link it @@ -306,8 +317,11 @@ function findHoleBridge(hole, outerNode) { // find a segment intersected by a ray from the hole's leftmost point to the left; // segment's endpoint with lesser x will be potential connection point + // unless they intersect at a vertex, then choose the vertex + if (equals(hole, p)) return p; do { - if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + if (equals(hole, p.next)) return p.next; + else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); if (x <= hx && x > qx) { qx = x; @@ -463,6 +477,11 @@ function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { (bx - px) * (cy - py) >= (cx - px) * (by - py); } +// check if a point lies within a convex triangle but false if its equal to the first point of the triangle +function pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, px, py) { + return !(ax === px && ay === py) && pointInTriangle(ax, ay, bx, by, cx, cy, px, py); +} + // check if a diagonal between two polygon nodes is valid (lies in polygon interior) function isValidDiagonal(a, b) { return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges diff --git a/test/expected.json b/test/expected.json index 046b8b0..c582373 100644 --- a/test/expected.json +++ b/test/expected.json @@ -7,7 +7,7 @@ "water3": 197, "water3b": 25, "water4": 705, - "water-huge": 5177, + "water-huge": 5176, "water-huge2": 4462, "degenerate": 0, "bad-hole": 42, @@ -22,6 +22,11 @@ "outside-ring": 64, "simplified-us-border": 120, "touching-holes": 57, + "touching-holes2": 10, + "touching-holes3": 82, + "touching-holes4": 55, + "touching-holes5": 133, + "touching-holes6": 3098, "hole-touching-outer": 77, "hilbert": 1024, "issue45": 10, @@ -32,18 +37,18 @@ "bad-diagonals": 7, "issue83": 0, "issue107": 0, - "issue111": 19, - "boxy": 57, + "issue111": 18, + "boxy": 58, "collinear-diagonal": 14, "issue119": 18, "hourglass": 2, "touching2": 8, "touching3": 15, - "touching4": 20, + "touching4": 19, "rain": 2681, "issue131": 12, - "infinite-loop-jhl" : 0, - "filtered-bridge-jhl" : 25, + "infinite-loop-jhl": 0, + "filtered-bridge-jhl": 25, "issue149": 2, "issue142": 4 }, @@ -51,7 +56,7 @@ "dude": 2e-15, "water": 0.0008, "water-huge": 0.0011, - "water-huge2": 0.0028, + "water-huge2": 0.004, "bad-hole": 0.019, "issue16": 4e-16, "issue17": 2e-16, @@ -59,5 +64,11 @@ "self-touching": 2e-13, "eberly-6": 2e-14, "issue142": 0.13 + }, + "errors-with-rotation": { + "water-huge": 0.0035, + "water-huge2": 0.061, + "bad-hole": 0.04, + "issue16": 8e-16 } -} +} \ No newline at end of file diff --git a/test/fixtures/touching-holes2.json b/test/fixtures/touching-holes2.json new file mode 100644 index 0000000..34c6431 --- /dev/null +++ b/test/fixtures/touching-holes2.json @@ -0,0 +1 @@ +[[[0,0],[20,0],[20,25],[0,25],[0,0]],[[3,3],[2,12],[9,15],[3,3]],[[9,21],[2,12],[7,22],[9,21]]] \ No newline at end of file diff --git a/test/fixtures/touching-holes3.json b/test/fixtures/touching-holes3.json new file mode 100644 index 0000000..6403078 --- /dev/null +++ b/test/fixtures/touching-holes3.json @@ -0,0 +1 @@ +[[[0,0],[20,0],[20,25],[0,25],[0,0]],[[2,12],[4,23],[5,23],[2,12]],[[2,12],[6,23],[7,23],[2,12]],[[2,12],[8,23],[9,23],[2,12]],[[2,12],[10,23],[11,23],[2,12]],[[2,12],[12,23],[13,23],[2,12]],[[2,12],[14,23],[15,23],[2,12]],[[2,12],[16,23],[17,23],[2,12]],[[2,12],[18,23],[18,22],[2,12]],[[2,12],[18,21],[18,20],[2,12]],[[2,12],[18,19],[18,18],[2,12]],[[2,12],[18,17],[18,16],[2,12]],[[2,12],[18,15],[18,14],[2,12]],[[2,12],[18,13],[18,12],[2,12]],[[2,12],[18,11],[18,10],[2,12]],[[2,12],[18,9],[18,8],[2,12]],[[2,12],[18,7],[18,6],[2,12]],[[2,12],[18,5],[18,4],[2,12]],[[2,12],[18,3],[18,2],[2,12]],[[2,12],[18,1],[17,1],[2,12]],[[2,12],[16,1],[15,1],[2,12]],[[2,12],[14,1],[13,1],[2,12]],[[2,12],[12,1],[11,1],[2,12]],[[2,12],[10,1],[9,1],[2,12]],[[2,12],[8,1],[7,1],[2,12]],[[2,12],[6,1],[5,1],[2,12]],[[2,12],[4,1],[3,1],[2,12]]] \ No newline at end of file diff --git a/test/fixtures/touching-holes4.json b/test/fixtures/touching-holes4.json new file mode 100644 index 0000000..5f5a434 --- /dev/null +++ b/test/fixtures/touching-holes4.json @@ -0,0 +1 @@ +[[[-20,0],[20,0],[20,25],[-20,25],[-20,0]],[[2,12],[-1,23],[0,23],[2,12]],[[2,12],[-3,23],[-2,23],[2,12]],[[2,12],[-5,23],[-4,23],[2,12]],[[2,12],[-7,23],[-6,23],[2,12]],[[2,12],[-9,23],[-8,23],[2,12]],[[2,12],[-11,23],[-10,23],[2,12]],[[2,12],[-13,23],[-12,23],[2,12]],[[2,12],[-14,22],[-14,23],[2,12]],[[2,12],[-14,20],[-14,21],[2,12]],[[2,12],[-14,18],[-14,19],[2,12]],[[2,12],[-14,16],[-14,17],[2,12]],[[2,12],[-14,14],[-14,15],[2,12]],[[2,12],[-14,12],[-14,13],[2,12]],[[2,12],[-14,10],[-14,11],[2,12]],[[2,12],[-14,8],[-14,9],[2,12]],[[2,12],[-14,6],[-14,7],[2,12]],[[2,12],[-14,4],[-14,5],[2,12]],[[2,12],[-14,2],[-14,3],[2,12]],[[2,12],[-13,1],[-14,1],[2,12]],[[2,12],[-11,1],[-12,1],[2,12]],[[2,12],[-9,1],[-10,1],[2,12]],[[2,12],[-7,1],[-8,1],[2,12]],[[2,12],[-5,1],[-6,1],[2,12]],[[2,12],[-3,1],[-4,1],[2,12]],[[2,12],[-1,1],[-2,1],[2,12]],[[2,12],[1,1],[0,1],[2,12]]] \ No newline at end of file diff --git a/test/fixtures/touching-holes5.json b/test/fixtures/touching-holes5.json new file mode 100644 index 0000000..414d5c6 --- /dev/null +++ b/test/fixtures/touching-holes5.json @@ -0,0 +1 @@ +[[[-20,0],[20,0],[20,25],[-20,25],[-20,0]],[[2,12],[4,23],[5,23],[2,12]],[[2,12],[6,23],[7,23],[2,12]],[[2,12],[8,23],[9,23],[2,12]],[[2,12],[10,23],[11,23],[2,12]],[[2,12],[12,23],[13,23],[2,12]],[[2,12],[14,23],[15,23],[2,12]],[[2,12],[16,23],[17,23],[2,12]],[[2,12],[18,23],[18,22],[2,12]],[[2,12],[18,21],[18,20],[2,12]],[[2,12],[18,19],[18,18],[2,12]],[[2,12],[18,17],[18,16],[2,12]],[[2,12],[18,15],[18,14],[2,12]],[[2,12],[18,13],[18,12],[2,12]],[[2,12],[18,11],[18,10],[2,12]],[[2,12],[18,9],[18,8],[2,12]],[[2,12],[18,7],[18,6],[2,12]],[[2,12],[18,5],[18,4],[2,12]],[[2,12],[18,3],[18,2],[2,12]],[[2,12],[18,1],[17,1],[2,12]],[[2,12],[16,1],[15,1],[2,12]],[[2,12],[14,1],[13,1],[2,12]],[[2,12],[12,1],[11,1],[2,12]],[[2,12],[10,1],[9,1],[2,12]],[[2,12],[8,1],[7,1],[2,12]],[[2,12],[6,1],[5,1],[2,12]],[[2,12],[4,1],[3,1],[2,12]],[[2,12],[-1,23],[0,23],[2,12]],[[2,12],[-3,23],[-2,23],[2,12]],[[2,12],[-5,23],[-4,23],[2,12]],[[2,12],[-7,23],[-6,23],[2,12]],[[2,12],[-9,23],[-8,23],[2,12]],[[2,12],[-11,23],[-10,23],[2,12]],[[2,12],[-13,23],[-12,23],[2,12]],[[2,12],[-14,22],[-14,23],[2,12]],[[2,12],[-14,20],[-14,21],[2,12]],[[2,12],[-14,18],[-14,19],[2,12]],[[2,12],[-14,16],[-14,17],[2,12]],[[2,12],[-14,14],[-14,15],[2,12]],[[2,12],[-14,12],[-14,13],[2,12]],[[2,12],[-14,10],[-14,11],[2,12]],[[2,12],[-14,8],[-14,9],[2,12]],[[2,12],[-14,6],[-14,7],[2,12]],[[2,12],[-14,4],[-14,5],[2,12]],[[2,12],[-14,2],[-14,3],[2,12]],[[2,12],[-13,1],[-14,1],[2,12]],[[2,12],[-11,1],[-12,1],[2,12]],[[2,12],[-9,1],[-10,1],[2,12]],[[2,12],[-7,1],[-8,1],[2,12]],[[2,12],[-5,1],[-6,1],[2,12]],[[2,12],[-3,1],[-4,1],[2,12]],[[2,12],[-1,1],[-2,1],[2,12]],[[2,12],[1,1],[0,1],[2,12]]] \ No newline at end of file diff --git a/test/fixtures/touching-holes6.json b/test/fixtures/touching-holes6.json new file mode 100644 index 0000000..709d71f --- /dev/null +++ b/test/fixtures/touching-holes6.json @@ -0,0 +1 @@ +[[[-56, 2836], [-45, 2831], [-41, 2835], [-48, 2838], [-52, 2836], [-64, 2848], [-64, 0], [4160, 0], [4160, 3451], [4139, 3445], [4141, 3451], [4136, 3450], [4133, 3456], [4127, 3456], [4126, 3452], [4117, 3452], [4115, 3448], [4111, 3453], [4103, 3452], [4102, 3455], [3968, 3456], [4094, 3456], [4091, 3463], [4086, 3463], [4086, 3468], [4073, 3472], [4059, 3492], [4046, 3500], [4043, 3508], [4034, 3520], [4034, 3526], [4040, 3550], [4040, 3561], [4061, 3548], [4071, 3551], [4076, 3550], [4091, 3535], [4096, 3534], [4112, 3538], [4121, 3547], [4133, 3545], [4155, 3536], [4160, 3535], [4160, 3842], [4147, 3827], [4129, 3816], [4120, 3805], [4117, 3809], [4110, 3809], [4096, 3800], [4069, 3768], [4045, 3748], [4025, 3738], [4005, 3736], [3981, 3720], [3968, 3719], [3940, 3706], [3930, 3698], [3918, 3683], [3903, 3683], [3874, 3688], [3845, 3688], [3840, 3685], [3828, 3683], [3816, 3687], [3813, 3685], [3812, 3692], [3809, 3683], [3799, 3676], [3790, 3679], [3792, 3684], [3801, 3693], [3798, 3697], [3789, 3699], [3786, 3695], [3791, 3693], [3770, 3680], [3766, 3671], [3754, 3675], [3712, 3663], [3662, 3651], [3661, 3654], [3667, 3658], [3665, 3679], [3667, 3683], [3667, 3700], [3652, 3706], [3648, 3719], [3650, 3722], [3665, 3720], [3671, 3725], [3672, 3737], [3676, 3740], [3676, 3750], [3679, 3750], [3683, 3762], [3681, 3776], [3686, 3779], [3688, 3785], [3679, 3800], [3661, 3814], [3647, 3823], [3624, 3826], [3617, 3821], [3614, 3815], [3616, 3805], [3613, 3790], [3610, 3787], [3600, 3786], [3584, 3773], [3566, 3771], [3562, 3766], [3560, 3743], [3563, 3727], [3554, 3721], [3547, 3712], [3552, 3708], [3553, 3703], [3546, 3697], [3538, 3698], [3514, 3726], [3500, 3737], [3496, 3734], [3470, 3732], [3456, 3726], [3427, 3721], [3405, 3724], [3393, 3722], [3381, 3712], [3374, 3700], [3369, 3699], [3358, 3709], [3345, 3710], [3337, 3706], [3321, 3712], [3303, 3710], [3296, 3712], [3231, 3712], [3212, 3710], [3202, 3712], [3200, 3707], [3191, 3705], [3191, 3710], [3185, 3700], [3176, 3693], [3171, 3683], [3180, 3669], [3183, 3648], [3190, 3633], [3183, 3603], [3174, 3584], [3167, 3573], [3156, 3563], [3123, 3540], [3087, 3527], [3072, 3525], [3056, 3521], [3001, 3520], [2944, 3534], [2922, 3541], [2898, 3552], [2897, 3549], [2867, 3557], [2845, 3555], [2827, 3547], [2825, 3541], [2816, 3539], [2807, 3535], [2804, 3533], [2804, 3531], [2816, 3535], [2825, 3531], [2816, 3514], [2810, 3497], [2802, 3486], [2775, 3477], [2770, 3468], [2763, 3468], [2761, 3460], [2741, 3457], [2738, 3453], [2732, 3455], [2730, 3456], [2730, 3437], [2726, 3436], [2710, 3439], [2704, 3437], [2700, 3432], [2696, 3435], [2691, 3431], [2688, 3436], [2689, 3422], [2694, 3420], [2699, 3410], [2704, 3407], [2701, 3404], [2709, 3405], [2712, 3417], [2717, 3424], [2734, 3413], [2736, 3406], [2731, 3392], [2718, 3373], [2704, 3361], [2688, 3353], [2684, 3353], [2657, 3340], [2616, 3339], [2600, 3342], [2586, 3361], [2582, 3373], [2560, 3408], [2553, 3418], [2539, 3430], [2534, 3427], [2523, 3437], [2518, 3434], [2512, 3437], [2501, 3431], [2503, 3426], [2499, 3421], [2505, 3422], [2512, 3416], [2514, 3411], [2505, 3402], [2504, 3396], [2512, 3398], [2518, 3407], [2530, 3399], [2537, 3401], [2541, 3396], [2540, 3383], [2533, 3382], [2532, 3374], [2536, 3363], [2539, 3363], [2540, 3355], [2534, 3356], [2532, 3351], [2537, 3349], [2546, 3359], [2543, 3365], [2551, 3357], [2547, 3374], [2553, 3370], [2551, 3364], [2556, 3365], [2558, 3361], [2563, 3370], [2550, 3384], [2549, 3381], [2547, 3407], [2556, 3394], [2569, 3380], [2592, 3342], [2560, 3342], [2513, 3348], [2493, 3354], [2483, 3365], [2472, 3360], [2469, 3354], [2471, 3345], [2480, 3353], [2492, 3328], [2502, 3323], [2508, 3328], [2514, 3323], [2518, 3328], [2521, 3337], [2526, 3334], [2533, 3336], [2560, 3336], [2588, 3337], [2560, 3322], [2529, 3308], [2478, 3293], [2432, 3284], [2364, 3279], [2349, 3273], [2337, 3260], [2310, 3254], [2308, 3257], [2310, 3267], [2314, 3269], [2322, 3284], [2330, 3290], [2329, 3297], [2332, 3301], [2321, 3300], [2318, 3311], [2314, 3309], [2304, 3315], [2283, 3318], [2267, 3313], [2257, 3314], [2246, 3328], [2237, 3349], [2239, 3361], [2248, 3365], [2258, 3354], [2272, 3353], [2278, 3346], [2279, 3354], [2296, 3357], [2281, 3367], [2273, 3363], [2271, 3372], [2266, 3377], [2259, 3394], [2251, 3391], [2253, 3380], [2247, 3390], [2249, 3395], [2263, 3399], [2269, 3409], [2266, 3412], [2266, 3432], [2270, 3446], [2277, 3456], [2274, 3456], [2277, 3463], [2271, 3459], [2271, 3465], [2266, 3468], [2264, 3463], [2253, 3461], [2249, 3473], [2241, 3473], [2237, 3456], [2237, 3448], [2230, 3447], [2222, 3440], [2212, 3444], [2215, 3449], [2207, 3456], [2206, 3447], [2194, 3448], [2191, 3445], [2190, 3456], [2184, 3472], [2182, 3481], [2186, 3480], [2194, 3485], [2187, 3487], [2191, 3492], [2200, 3493], [2198, 3497], [2193, 3496], [2188, 3501], [2179, 3493], [2176, 3500], [2185, 3501], [2192, 3511], [2187, 3518], [2184, 3509], [2180, 3516], [2177, 3515], [2176, 3506], [2163, 3489], [2166, 3479], [2158, 3480], [2157, 3475], [2144, 3471], [2137, 3464], [2136, 3456], [2127, 3454], [2121, 3456], [2127, 3450], [2107, 3447], [2093, 3439], [2087, 3438], [2078, 3440], [2065, 3450], [2048, 3456], [2040, 3466], [2048, 3476], [2037, 3472], [2042, 3479], [2035, 3474], [2021, 3479], [2006, 3477], [1986, 3468], [1972, 3456], [1964, 3446], [1955, 3425], [1949, 3424], [1946, 3418], [1949, 3411], [1947, 3398], [1952, 3398], [1962, 3393], [1972, 3408], [1965, 3393], [1961, 3391], [1945, 3395], [1940, 3400], [1926, 3430], [1920, 3451], [1920, 3328], [1919, 3456], [1911, 3494], [1920, 3501], [1909, 3501], [1905, 3507], [1906, 3511], [1894, 3550], [1881, 3569], [1869, 3571], [1864, 3566], [1863, 3553], [1859, 3541], [1854, 3551], [1847, 3551], [1845, 3542], [1837, 3544], [1832, 3537], [1833, 3533], [1828, 3521], [1813, 3514], [1808, 3499], [1796, 3488], [1792, 3456], [1792, 3467], [1788, 3460], [1789, 3456], [1784, 3444], [1772, 3448], [1770, 3439], [1774, 3430], [1792, 3426], [1802, 3430], [1792, 3417], [1792, 3410], [1780, 3386], [1787, 3416], [1780, 3423], [1771, 3425], [1765, 3422], [1760, 3406], [1756, 3403], [1752, 3394], [1752, 3381], [1745, 3376], [1744, 3369], [1735, 3364], [1734, 3358], [1726, 3352], [1720, 3339], [1713, 3333], [1708, 3333], [1704, 3325], [1701, 3328], [1693, 3326], [1684, 3328], [1682, 3326], [1668, 3328], [1664, 3321], [1665, 3309], [1680, 3305], [1702, 3282], [1719, 3281], [1723, 3272], [1730, 3269], [1737, 3271], [1745, 3263], [1753, 3265], [1758, 3270], [1768, 3269], [1786, 3272], [1792, 3271], [1792, 3269], [1794, 3264], [1792, 3255], [1758, 3258], [1764, 3254], [1754, 3256], [1746, 3248], [1756, 3249], [1766, 3246], [1780, 3235], [1784, 3221], [1779, 3216], [1773, 3222], [1769, 3214], [1766, 3214], [1770, 3205], [1764, 3197], [1755, 3197], [1747, 3200], [1749, 3196], [1746, 3194], [1746, 3195], [1741, 3200], [1745, 3187], [1746, 3193], [1751, 3190], [1751, 3181], [1740, 3177], [1731, 3185], [1727, 3185], [1735, 3172], [1734, 3171], [1717, 3176], [1722, 3162], [1711, 3163], [1709, 3166], [1705, 3161], [1704, 3171], [1701, 3171], [1700, 3156], [1696, 3153], [1684, 3154], [1685, 3170], [1683, 3165], [1679, 3171], [1682, 3177], [1678, 3177], [1676, 3165], [1670, 3176], [1667, 3165], [1664, 3169], [1664, 3072], [1663, 3179], [1659, 3175], [1654, 3181], [1649, 3164], [1655, 3173], [1659, 3167], [1659, 3155], [1655, 3154], [1652, 3148], [1644, 3154], [1642, 3160], [1635, 3153], [1635, 3158], [1626, 3166], [1624, 3165], [1624, 3152], [1616, 3152], [1615, 3144], [1613, 3153], [1609, 3149], [1602, 3155], [1603, 3135], [1598, 3135], [1594, 3141], [1594, 3125], [1590, 3133], [1589, 3121], [1580, 3126], [1581, 3117], [1571, 3119], [1566, 3114], [1567, 3108], [1563, 3109], [1561, 3123], [1554, 3129], [1549, 3130], [1548, 3141], [1545, 3136], [1543, 3143], [1540, 3137], [1536, 3146], [1532, 3135], [1535, 3126], [1529, 3126], [1530, 3131], [1521, 3132], [1521, 3140], [1525, 3148], [1519, 3143], [1520, 3150], [1516, 3151], [1519, 3157], [1517, 3161], [1522, 3165], [1519, 3173], [1521, 3177], [1526, 3176], [1519, 3182], [1525, 3189], [1524, 3198], [1528, 3205], [1536, 3203], [1527, 3212], [1535, 3220], [1524, 3218], [1520, 3228], [1522, 3240], [1518, 3241], [1512, 3252], [1506, 3246], [1493, 3240], [1501, 3240], [1487, 3228], [1481, 3236], [1484, 3240], [1478, 3242], [1486, 3246], [1485, 3242], [1488, 3247], [1499, 3253], [1494, 3257], [1489, 3249], [1483, 3249], [1488, 3257], [1486, 3260], [1479, 3254], [1476, 3256], [1461, 3251], [1444, 3241], [1430, 3242], [1415, 3247], [1408, 3246], [1395, 3240], [1372, 3237], [1362, 3233], [1352, 3237], [1342, 3228], [1326, 3222], [1298, 3208], [1293, 3200], [1292, 3191], [1296, 3180], [1292, 3176], [1295, 3167], [1300, 3161], [1306, 3164], [1311, 3162], [1317, 3165], [1321, 3159], [1305, 3147], [1280, 3144], [1248, 3144], [1212, 3130], [1197, 3132], [1174, 3124], [1159, 3123], [1152, 3124], [1141, 3131], [1134, 3141], [1119, 3143], [1102, 3141], [1089, 3150], [1070, 3156], [1075, 3169], [1086, 3181], [1082, 3185], [1078, 3195], [1073, 3200], [1077, 3210], [1070, 3211], [1069, 3200], [1072, 3193], [1072, 3182], [1064, 3178], [1055, 3165], [1062, 3145], [1068, 3140], [1066, 3130], [1055, 3097], [1047, 3089], [1039, 3075], [1047, 3107], [1046, 3113], [1039, 3121], [1024, 3124], [1015, 3124], [996, 3120], [981, 3112], [970, 3099], [965, 3083], [967, 3075], [973, 3078], [983, 3072], [981, 3067], [968, 3068], [962, 3072], [959, 3080], [960, 3088], [955, 3092], [941, 3079], [931, 3074], [923, 3073], [909, 3075], [904, 3095], [889, 3108], [891, 3120], [896, 3129], [898, 3127], [916, 3124], [924, 3128], [928, 3120], [938, 3116], [941, 3109], [951, 3113], [949, 3121], [954, 3124], [951, 3129], [932, 3135], [927, 3139], [929, 3143], [921, 3147], [915, 3147], [919, 3151], [916, 3157], [911, 3158], [903, 3166], [891, 3166], [884, 3161], [875, 3148], [874, 3158], [880, 3157], [886, 3166], [885, 3171], [876, 3161], [875, 3168], [879, 3174], [867, 3178], [861, 3183], [857, 3182], [830, 3190], [828, 3197], [835, 3195], [838, 3200], [821, 3200], [809, 3211], [790, 3212], [775, 3210], [768, 3215], [760, 3214], [744, 3206], [757, 3189], [766, 3184], [768, 3168], [783, 3151], [776, 3141], [775, 3135], [782, 3139], [802, 3136], [810, 3138], [823, 3129], [824, 3136], [841, 3113], [854, 3086], [865, 3072], [873, 3065], [889, 3062], [896, 3052], [906, 3042], [908, 3025], [901, 3021], [913, 3013], [915, 3009], [919, 3015], [929, 3002], [928, 2991], [937, 2993], [949, 2986], [947, 2984], [958, 2982], [965, 2970], [975, 2960], [987, 2961], [992, 2966], [1003, 2944], [1009, 2929], [1015, 2923], [1030, 2918], [1039, 2912], [1045, 2899], [1050, 2896], [1076, 2855], [1079, 2837], [1071, 2836], [1075, 2831], [1080, 2832], [1079, 2816], [1152, 2816], [1072, 2815], [1063, 2811], [1060, 2803], [1062, 2791], [1059, 2786], [1046, 2795], [1048, 2807], [1038, 2807], [1038, 2797], [1042, 2792], [1037, 2788], [1042, 2776], [1034, 2766], [1024, 2766], [1023, 2756], [1017, 2752], [1024, 2752], [1031, 2756], [1042, 2770], [1050, 2773], [1054, 2778], [1047, 2785], [1062, 2781], [1074, 2788], [1074, 2796], [1065, 2806], [1071, 2810], [1080, 2795], [1087, 2767], [1089, 2752], [1085, 2744], [1088, 2742], [1082, 2736], [1080, 2737], [1073, 2739], [1077, 2751], [1070, 2740], [1074, 2732], [1071, 2726], [1072, 2720], [1067, 2712], [1069, 2702], [1066, 2688], [1059, 2674], [1056, 2679], [1053, 2676], [1044, 2678], [1048, 2688], [1054, 2688], [1061, 2695], [1050, 2695], [1046, 2700], [1049, 2708], [1041, 2714], [1033, 2714], [1042, 2706], [1037, 2689], [1030, 2690], [1024, 2679], [1027, 2678], [1034, 2685], [1034, 2668], [1038, 2662], [1024, 2649], [1016, 2638], [1004, 2655], [1001, 2654], [1012, 2638], [1006, 2627], [1000, 2624], [1001, 2618], [989, 2608], [981, 2608], [980, 2602], [985, 2596], [980, 2593], [962, 2589], [967, 2580], [961, 2577], [947, 2585], [941, 2584], [942, 2578], [928, 2581], [915, 2591], [902, 2589], [884, 2578], [874, 2586], [870, 2584], [843, 2589], [838, 2583], [832, 2590], [835, 2581], [820, 2581], [817, 2583], [818, 2597], [821, 2601], [820, 2610], [815, 2621], [802, 2629], [792, 2622], [779, 2625], [775, 2628], [768, 2628], [768, 2636], [762, 2630], [755, 2631], [748, 2625], [749, 2617], [747, 2612], [754, 2609], [756, 2620], [762, 2612], [764, 2605], [763, 2598], [767, 2594], [764, 2591], [764, 2583], [771, 2585], [776, 2579], [777, 2569], [785, 2568], [788, 2561], [783, 2560], [792, 2555], [785, 2553], [785, 2549], [791, 2550], [798, 2545], [788, 2539], [790, 2535], [784, 2529], [788, 2526], [775, 2530], [768, 2519], [762, 2519], [758, 2529], [756, 2523], [751, 2527], [749, 2520], [737, 2517], [724, 2531], [718, 2530], [708, 2537], [703, 2531], [708, 2522], [715, 2525], [720, 2523], [718, 2518], [724, 2515], [723, 2507], [720, 2510], [712, 2508], [701, 2514], [692, 2510], [686, 2517], [676, 2513], [673, 2506], [670, 2512], [654, 2514], [649, 2511], [643, 2513], [658, 2503], [662, 2504], [668, 2496], [675, 2494], [680, 2497], [699, 2488], [710, 2477], [706, 2475], [712, 2471], [721, 2458], [719, 2453], [737, 2459], [742, 2453], [730, 2444], [726, 2432], [725, 2414], [712, 2414], [711, 2417], [700, 2417], [676, 2404], [674, 2400], [675, 2389], [666, 2387], [662, 2391], [650, 2389], [655, 2385], [650, 2378], [645, 2382], [642, 2379], [627, 2396], [628, 2402], [623, 2399], [612, 2403], [608, 2397], [605, 2398], [591, 2410], [592, 2417], [576, 2426], [567, 2443], [564, 2453], [557, 2457], [560, 2463], [550, 2458], [519, 2506], [513, 2519], [512, 2535], [504, 2537], [498, 2560], [504, 2578], [512, 2579], [515, 2588], [520, 2592], [518, 2595], [509, 2593], [504, 2620], [501, 2620], [492, 2629], [471, 2637], [460, 2634], [443, 2639], [427, 2637], [407, 2627], [403, 2635], [411, 2646], [414, 2660], [423, 2659], [428, 2666], [428, 2671], [438, 2674], [437, 2683], [439, 2688], [425, 2688], [425, 2684], [409, 2681], [401, 2685], [399, 2683], [404, 2676], [402, 2674], [390, 2683], [388, 2687], [377, 2693], [373, 2692], [362, 2701], [366, 2705], [377, 2705], [374, 2710], [371, 2708], [361, 2715], [357, 2706], [344, 2716], [354, 2717], [358, 2729], [350, 2729], [343, 2724], [335, 2727], [333, 2737], [327, 2737], [331, 2732], [327, 2726], [336, 2721], [335, 2718], [318, 2730], [316, 2738], [310, 2743], [307, 2741], [303, 2746], [296, 2745], [305, 2729], [303, 2726], [294, 2728], [299, 2722], [293, 2722], [281, 2735], [279, 2730], [273, 2735], [262, 2755], [256, 2746], [259, 2746], [269, 2727], [274, 2724], [280, 2714], [276, 2715], [275, 2710], [286, 2705], [280, 2702], [275, 2703], [268, 2696], [258, 2697], [257, 2691], [264, 2695], [273, 2693], [278, 2696], [286, 2694], [290, 2700], [295, 2691], [292, 2688], [284, 2682], [292, 2681], [292, 2672], [295, 2669], [292, 2664], [286, 2666], [284, 2676], [279, 2681], [281, 2668], [273, 2668], [270, 2674], [268, 2663], [258, 2670], [256, 2677], [250, 2674], [253, 2670], [245, 2669], [243, 2679], [247, 2684], [251, 2683], [256, 2688], [256, 2695], [248, 2692], [243, 2703], [237, 2700], [231, 2706], [225, 2701], [223, 2694], [210, 2693], [208, 2697], [219, 2697], [220, 2703], [211, 2702], [214, 2708], [201, 2704], [201, 2698], [191, 2704], [188, 2698], [180, 2702], [170, 2700], [169, 2705], [182, 2710], [184, 2714], [173, 2713], [170, 2709], [163, 2717], [156, 2722], [158, 2715], [153, 2710], [160, 2704], [157, 2701], [148, 2711], [147, 2719], [141, 2722], [139, 2716], [141, 2710], [134, 2713], [136, 2724], [132, 2730], [134, 2738], [141, 2735], [150, 2726], [153, 2726], [149, 2735], [152, 2736], [158, 2747], [162, 2747], [159, 2738], [163, 2733], [167, 2745], [178, 2741], [179, 2738], [188, 2737], [187, 2740], [179, 2742], [177, 2748], [168, 2747], [167, 2750], [158, 2752], [150, 2758], [146, 2756], [137, 2761], [128, 2763], [128, 2755], [131, 2756], [130, 2748], [121, 2756], [127, 2754], [127, 2763], [120, 2766], [116, 2764], [112, 2770], [106, 2773], [99, 2771], [94, 2778], [91, 2774], [81, 2778], [79, 2773], [74, 2781], [78, 2795], [69, 2790], [56, 2792], [57, 2785], [52, 2787], [44, 2798], [41, 2790], [31, 2791], [33, 2794], [20, 2801], [14, 2799], [0, 2805], [-3, 2808], [2, 2813], [0, 2816], [-6, 2816], [-28, 2816], [-32, 2813], [-33, 2816], [-39, 2827], [-43, 2826], [-57, 2834], [-56, 2836]], [[139, 2737], [134, 2738], [134, 2742], [141, 2745], [144, 2742], [139, 2737]], [[299, 2686], [292, 2688], [299, 2689], [298, 2698], [302, 2694], [300, 2683], [303, 2682], [305, 2674], [297, 2669], [295, 2671], [299, 2686]], [[1075, 2734], [1080, 2737], [1080, 2730], [1075, 2734]], [[1313, 3166], [1311, 3162], [1307, 3165], [1313, 3166]], [[1523, 3211], [1527, 3212], [1530, 3206], [1523, 3211]], [[1536, 3140], [1540, 3137], [1541, 3134], [1538, 3133], [1536, 3140]], [[1541, 3121], [1541, 3134], [1543, 3127], [1541, 3121]], [[2731, 3440], [2732, 3455], [2738, 3447], [2731, 3440]], [[70, 1512], [66, 1506], [48, 1496], [48, 1500], [26, 1502], [9, 1510], [7, 1522], [11, 1536], [30, 1550], [43, 1553], [61, 1548], [69, 1536], [74, 1527], [70, 1512]], [[99, 1797], [128, 1804], [139, 1811], [163, 1836], [173, 1840], [188, 1828], [192, 1829], [210, 1809], [218, 1810], [220, 1801], [232, 1800], [243, 1793], [250, 1792], [256, 1786], [266, 1782], [305, 1783], [321, 1780], [327, 1777], [333, 1780], [332, 1774], [341, 1763], [341, 1753], [331, 1746], [326, 1745], [331, 1739], [332, 1731], [330, 1726], [334, 1718], [329, 1712], [326, 1702], [322, 1699], [334, 1694], [325, 1690], [326, 1683], [333, 1680], [328, 1679], [332, 1673], [325, 1667], [328, 1666], [333, 1672], [339, 1673], [345, 1669], [343, 1665], [349, 1663], [353, 1668], [359, 1662], [361, 1656], [367, 1657], [365, 1651], [357, 1646], [362, 1640], [358, 1638], [359, 1630], [355, 1632], [354, 1626], [332, 1609], [325, 1597], [317, 1588], [309, 1586], [307, 1570], [310, 1566], [302, 1559], [297, 1550], [296, 1540], [286, 1529], [286, 1524], [280, 1518], [277, 1507], [271, 1508], [270, 1502], [273, 1497], [263, 1483], [256, 1483], [238, 1490], [236, 1493], [240, 1500], [256, 1501], [254, 1506], [241, 1508], [238, 1517], [236, 1516], [225, 1529], [222, 1536], [199, 1545], [192, 1555], [187, 1554], [179, 1559], [172, 1558], [175, 1564], [171, 1567], [166, 1562], [160, 1562], [154, 1570], [155, 1574], [146, 1575], [144, 1582], [148, 1584], [145, 1589], [149, 1594], [145, 1595], [131, 1609], [133, 1613], [118, 1641], [120, 1646], [135, 1642], [149, 1636], [148, 1632], [153, 1627], [158, 1631], [152, 1636], [155, 1640], [141, 1661], [138, 1664], [130, 1679], [133, 1713], [112, 1715], [109, 1720], [103, 1722], [99, 1731], [106, 1736], [125, 1742], [122, 1747], [114, 1742], [106, 1743], [95, 1741], [75, 1752], [68, 1770], [76, 1766], [81, 1769], [90, 1767], [110, 1768], [106, 1771], [109, 1779], [128, 1792], [114, 1791], [0, 1792], [102, 1792], [99, 1797]], [[128, 1704], [128, 1699], [122, 1706], [128, 1704]], [[191, 1835], [201, 1832], [197, 1826], [191, 1835]], [[194, 1841], [191, 1835], [186, 1834], [180, 1846], [194, 1841]], [[117, 1834], [118, 1827], [106, 1829], [92, 1823], [89, 1818], [68, 1822], [65, 1825], [45, 1823], [52, 1826], [57, 1833], [59, 1845], [52, 1851], [60, 1857], [63, 1862], [60, 1868], [53, 1872], [54, 1881], [73, 1888], [72, 1886], [89, 1891], [96, 1888], [109, 1901], [108, 1912], [103, 1910], [102, 1905], [96, 1905], [99, 1912], [90, 1915], [97, 1918], [91, 1920], [108, 1925], [122, 1924], [144, 1915], [151, 1902], [155, 1900], [159, 1892], [169, 1883], [176, 1863], [173, 1858], [168, 1857], [149, 1838], [134, 1831], [128, 1832], [128, 1828], [127, 1833], [117, 1834]], [[81, 1913], [86, 1909], [71, 1909], [57, 1906], [56, 1914], [60, 1920], [77, 1931], [83, 1930], [91, 1924], [89, 1920], [89, 1916], [81, 1913]], [[29, 1957], [35, 1956], [25, 1954], [29, 1957]], [[67, 1977], [63, 1978], [80, 1985], [70, 1977], [59, 1964], [40, 1955], [62, 1970], [67, 1977]], [[97, 1989], [82, 1986], [106, 1996], [106, 1990], [114, 1982], [104, 1982], [97, 1989]], [[139, 1985], [131, 1982], [122, 1987], [128, 1996], [137, 1993], [139, 1985]], [[104, 2058], [109, 2064], [128, 2074], [132, 2074], [104, 2058]], [[166, 2279], [173, 2284], [171, 2276], [167, 2272], [166, 2279]], [[85, 2401], [91, 2404], [95, 2399], [88, 2392], [84, 2393], [85, 2401]], [[35, 2473], [35, 2464], [32, 2464], [35, 2473]], [[-12, 2477], [-14, 2469], [-21, 2466], [-29, 2468], [-36, 2483], [-34, 2493], [-21, 2495], [-14, 2483], [-17, 2471], [-12, 2477]], [[452, 1941], [454, 1948], [460, 1931], [469, 1927], [468, 1923], [462, 1925], [462, 1920], [460, 1915], [452, 1941]], [[456, 1993], [461, 1983], [455, 1980], [454, 1983], [453, 1992], [456, 1993]], [[609, 2036], [607, 2048], [614, 2048], [615, 2041], [609, 2036]], [[614, 2063], [612, 2054], [609, 2054], [614, 2063]], [[647, 2086], [653, 2085], [656, 2080], [647, 2086]], [[392, 2137], [390, 2142], [395, 2142], [392, 2137]], [[473, 2188], [467, 2196], [467, 2210], [462, 2226], [457, 2227], [460, 2232], [460, 2242], [455, 2253], [438, 2282], [432, 2304], [427, 2315], [431, 2317], [432, 2328], [436, 2335], [444, 2330], [458, 2329], [487, 2304], [491, 2304], [506, 2291], [512, 2282], [519, 2279], [547, 2278], [552, 2281], [557, 2276], [567, 2276], [571, 2273], [580, 2275], [582, 2288], [592, 2279], [589, 2275], [596, 2270], [604, 2274], [614, 2266], [626, 2266], [655, 2249], [662, 2250], [671, 2247], [675, 2252], [681, 2246], [702, 2207], [704, 2196], [700, 2185], [702, 2176], [700, 2173], [701, 2161], [696, 2155], [700, 2153], [695, 2136], [679, 2124], [673, 2129], [675, 2132], [673, 2141], [670, 2132], [657, 2125], [662, 2126], [668, 2121], [662, 2117], [664, 2108], [658, 2093], [649, 2089], [643, 2090], [643, 2080], [638, 2077], [640, 2072], [640, 2058], [633, 2058], [633, 2048], [630, 2055], [628, 2052], [623, 2063], [624, 2048], [619, 2048], [616, 2064], [608, 2069], [600, 2080], [594, 2081], [591, 2078], [588, 2099], [583, 2114], [579, 2117], [580, 2122], [575, 2124], [577, 2129], [571, 2136], [566, 2132], [573, 2120], [572, 2114], [579, 2107], [581, 2098], [581, 2074], [587, 2060], [584, 2057], [585, 2048], [593, 2024], [596, 2026], [602, 2016], [594, 2016], [596, 2011], [586, 1997], [569, 1990], [567, 1985], [560, 1989], [556, 2004], [561, 2036], [557, 2037], [546, 2032], [545, 2017], [539, 2002], [534, 2007], [531, 2005], [528, 2013], [531, 2034], [517, 2036], [512, 2048], [512, 2058], [521, 2063], [507, 2065], [504, 2077], [512, 2083], [520, 2092], [531, 2097], [531, 2100], [515, 2093], [506, 2086], [501, 2087], [501, 2097], [492, 2124], [495, 2130], [496, 2139], [512, 2147], [512, 2151], [506, 2153], [505, 2148], [492, 2143], [487, 2136], [473, 2164], [472, 2176], [397, 2176], [472, 2177], [473, 2188]], [[748, 2266], [761, 2255], [765, 2262], [766, 2250], [761, 2250], [759, 2244], [751, 2249], [747, 2266], [744, 2262], [734, 2264], [734, 2273], [741, 2278], [754, 2266], [748, 2266]], [[274, 1806], [280, 1803], [277, 1798], [272, 1803], [274, 1806]], [[164, 1937], [154, 1951], [152, 1956], [138, 1949], [132, 1952], [141, 1953], [140, 1959], [143, 1962], [146, 1958], [153, 1960], [153, 1968], [145, 1970], [144, 1975], [149, 1980], [158, 1978], [153, 1976], [161, 1969], [155, 1965], [167, 1949], [168, 1954], [176, 1957], [174, 1960], [183, 1966], [179, 1972], [171, 1975], [178, 1983], [183, 1984], [185, 1978], [182, 1970], [196, 1971], [200, 1975], [202, 1985], [198, 1990], [201, 2005], [195, 2008], [194, 2017], [202, 2023], [199, 2032], [215, 2048], [213, 2063], [222, 2077], [231, 2083], [236, 2081], [250, 2065], [258, 2066], [256, 2073], [262, 2076], [261, 2091], [278, 2093], [290, 2085], [296, 2093], [312, 2087], [317, 2095], [317, 2105], [322, 2108], [327, 2117], [332, 2119], [340, 2129], [348, 2135], [356, 2132], [363, 2138], [367, 2134], [372, 2137], [378, 2136], [381, 2143], [388, 2141], [391, 2135], [413, 2136], [422, 2133], [432, 2135], [435, 2125], [455, 2107], [452, 2093], [448, 2086], [452, 2078], [451, 2071], [447, 2067], [436, 2062], [434, 2058], [442, 2055], [429, 2042], [416, 2020], [422, 2016], [436, 2030], [442, 2027], [441, 2022], [446, 2024], [446, 2003], [444, 2001], [447, 1989], [444, 1983], [449, 1968], [445, 1955], [448, 1935], [453, 1925], [452, 1908], [458, 1904], [460, 1889], [456, 1886], [450, 1875], [450, 1868], [446, 1860], [439, 1852], [435, 1856], [434, 1851], [439, 1849], [425, 1844], [430, 1841], [431, 1836], [427, 1833], [423, 1838], [416, 1837], [425, 1830], [414, 1826], [411, 1831], [401, 1833], [401, 1830], [391, 1822], [392, 1828], [386, 1839], [389, 1845], [389, 1855], [384, 1866], [384, 1873], [380, 1875], [379, 1884], [364, 1882], [354, 1883], [349, 1879], [354, 1869], [361, 1865], [363, 1854], [359, 1851], [362, 1843], [361, 1835], [366, 1834], [365, 1828], [368, 1823], [363, 1819], [359, 1810], [353, 1805], [349, 1795], [327, 1795], [314, 1811], [303, 1809], [302, 1803], [298, 1812], [288, 1815], [286, 1809], [281, 1818], [279, 1811], [269, 1812], [265, 1809], [261, 1815], [256, 1810], [251, 1812], [247, 1819], [245, 1833], [239, 1831], [236, 1825], [230, 1821], [233, 1817], [228, 1810], [225, 1812], [228, 1822], [220, 1827], [215, 1843], [206, 1845], [205, 1848], [198, 1845], [201, 1856], [197, 1861], [197, 1868], [215, 1886], [215, 1892], [209, 1892], [209, 1897], [196, 1896], [185, 1901], [175, 1920], [167, 1936], [164, 1937]], [[249, 2531], [256, 2532], [272, 2526], [274, 2528], [269, 2536], [265, 2534], [260, 2546], [278, 2530], [283, 2533], [289, 2527], [299, 2503], [294, 2492], [275, 2510], [256, 2519], [248, 2527], [249, 2531]], [[270, 2546], [266, 2543], [264, 2548], [270, 2546]], [[794, 2299], [796, 2309], [804, 2304], [809, 2290], [806, 2282], [797, 2277], [787, 2284], [774, 2283], [770, 2280], [764, 2285], [754, 2287], [754, 2292], [768, 2298], [790, 2303], [794, 2299]], [[523, 2396], [517, 2398], [519, 2403], [523, 2396]], [[768, 2438], [763, 2433], [756, 2443], [752, 2452], [762, 2452], [763, 2445], [768, 2444], [772, 2435], [768, 2438]], [[558, 2450], [549, 2455], [556, 2454], [558, 2450]], [[-43, 2504], [-49, 2501], [-56, 2505], [-43, 2504]], [[5, 2510], [9, 2507], [4, 2502], [0, 2503], [-2, 2506], [5, 2510]], [[-57, 2508], [-58, 2517], [-51, 2520], [-48, 2512], [-54, 2507], [-57, 2508]], [[-51, 2526], [-58, 2517], [-53, 2527], [-51, 2526]], [[265, 2590], [266, 2583], [259, 2584], [259, 2589], [265, 2590]], [[251, 2588], [248, 2584], [247, 2590], [251, 2588]], [[276, 2595], [277, 2587], [272, 2584], [269, 2595], [276, 2595]], [[201, 2591], [203, 2598], [206, 2598], [207, 2592], [201, 2591]], [[247, 2596], [249, 2603], [261, 2603], [267, 2597], [259, 2593], [256, 2599], [254, 2592], [247, 2596]], [[246, 2601], [239, 2600], [234, 2590], [232, 2598], [220, 2601], [223, 2608], [226, 2605], [241, 2605], [246, 2601]], [[289, 2604], [285, 2601], [292, 2597], [294, 2592], [288, 2594], [282, 2591], [278, 2602], [275, 2599], [268, 2602], [268, 2612], [275, 2606], [276, 2609], [284, 2612], [289, 2604]], [[217, 2599], [209, 2602], [209, 2605], [215, 2604], [217, 2599]], [[274, 2615], [273, 2621], [277, 2619], [274, 2615]], [[248, 2617], [243, 2627], [249, 2621], [248, 2617]], [[229, 2638], [227, 2646], [233, 2642], [234, 2637], [229, 2638]], [[278, 2658], [279, 2663], [283, 2660], [278, 2658]], [[733, 2465], [730, 2461], [730, 2470], [733, 2465]], [[746, 2468], [750, 2464], [742, 2465], [746, 2468]], [[804, 2471], [808, 2467], [805, 2460], [801, 2465], [793, 2458], [791, 2467], [788, 2466], [787, 2473], [795, 2473], [796, 2478], [784, 2484], [795, 2484], [798, 2481], [807, 2474], [804, 2471]], [[721, 2479], [724, 2480], [729, 2472], [726, 2470], [721, 2472], [721, 2479]], [[816, 2540], [820, 2537], [818, 2533], [816, 2540]], [[342, 2560], [346, 2564], [346, 2555], [342, 2560]], [[334, 2564], [342, 2560], [339, 2557], [333, 2560], [334, 2564]], [[313, 2562], [333, 2560], [298, 2560], [313, 2562]], [[256, 2560], [298, 2560], [299, 2558], [256, 2560]], [[351, 2566], [359, 2569], [358, 2565], [351, 2566]], [[290, 2549], [281, 2544], [266, 2551], [274, 2555], [282, 2555], [290, 2549]], [[207, 2586], [202, 2580], [203, 2587], [207, 2586]], [[326, 2578], [328, 2581], [339, 2581], [340, 2585], [344, 2578], [348, 2582], [348, 2574], [326, 2578]], [[340, 2599], [340, 2588], [338, 2595], [340, 2599]], [[345, 2610], [340, 2599], [338, 2606], [333, 2611], [345, 2610]], [[327, 2722], [328, 2715], [336, 2707], [335, 2703], [321, 2710], [306, 2724], [309, 2728], [320, 2723], [327, 2722]], [[197, 2604], [207, 2606], [201, 2599], [197, 2604]], [[202, 2618], [197, 2614], [180, 2611], [181, 2616], [185, 2614], [190, 2619], [196, 2616], [198, 2620], [202, 2618]], [[123, 2723], [117, 2723], [117, 2728], [122, 2729], [123, 2723]], [[303, 2668], [308, 2660], [303, 2657], [295, 2657], [289, 2660], [303, 2663], [303, 2668]], [[307, 2692], [312, 2685], [323, 2681], [318, 2674], [307, 2687], [308, 2681], [316, 2668], [318, 2673], [324, 2668], [321, 2660], [312, 2664], [308, 2672], [304, 2688], [307, 2692]], [[215, 2685], [224, 2690], [225, 2683], [222, 2677], [232, 2671], [226, 2669], [223, 2675], [218, 2674], [221, 2683], [217, 2684], [210, 2680], [202, 2685], [206, 2688], [215, 2685]], [[235, 2682], [232, 2688], [228, 2692], [233, 2695], [240, 2692], [235, 2691], [239, 2687], [235, 2682]], [[-21, 2811], [-15, 2808], [-23, 2808], [-21, 2811]], [[993, 2607], [995, 2602], [989, 2603], [993, 2607]], [[1030, 2642], [1031, 2653], [1034, 2641], [1030, 2637], [1029, 2628], [1025, 2625], [1029, 2620], [1024, 2615], [1023, 2605], [1017, 2610], [1021, 2603], [1015, 2601], [1014, 2605], [1009, 2604], [1000, 2608], [1005, 2610], [1004, 2621], [1014, 2622], [1021, 2638], [1024, 2640], [1030, 2642]], [[1056, 2656], [1069, 2656], [1064, 2650], [1060, 2651], [1062, 2644], [1059, 2641], [1054, 2652], [1056, 2656]], [[961, 3029], [966, 3030], [965, 3023], [960, 3023], [961, 3029]], [[1002, 2983], [1002, 3000], [1006, 3001], [1002, 3011], [1004, 3015], [994, 3021], [991, 3015], [985, 3014], [980, 3018], [979, 3024], [983, 3032], [999, 3039], [1011, 3053], [1024, 3056], [1031, 3061], [1039, 3062], [1046, 3045], [1057, 3040], [1061, 3027], [1065, 3021], [1067, 3009], [1065, 3000], [1057, 2993], [1048, 2990], [1024, 2988], [1002, 2983]], [[1510, 3085], [1517, 3088], [1511, 3081], [1510, 3085]], [[1507, 3098], [1510, 3101], [1510, 3094], [1507, 3098]], [[1540, 3119], [1540, 3113], [1534, 3117], [1536, 3121], [1540, 3119]], [[1366, 3232], [1374, 3233], [1378, 3227], [1384, 3226], [1379, 3217], [1369, 3219], [1358, 3227], [1363, 3228], [1366, 3232]], [[1353, 3233], [1348, 3220], [1349, 3230], [1353, 3233]], [[1475, 3234], [1477, 3229], [1471, 3226], [1475, 3234]], [[1478, 3229], [1477, 3238], [1480, 3232], [1478, 3229]], [[3029, 2506], [3025, 2513], [3032, 2513], [3032, 2506], [3029, 2506]], [[2697, 2598], [2697, 2588], [2701, 2581], [2708, 2577], [2688, 2582], [2678, 2583], [2661, 2600], [2688, 2597], [2694, 2602], [2697, 2598]], [[2846, 2695], [2856, 2706], [2860, 2705], [2860, 2688], [2850, 2689], [2846, 2695]], [[2325, 2707], [2318, 2706], [2324, 2710], [2325, 2707]], [[2336, 2709], [2331, 2705], [2333, 2712], [2336, 2709]], [[2312, 2786], [2304, 2779], [2304, 2791], [2308, 2792], [2312, 2786]], [[2308, 2797], [2304, 2791], [2301, 2795], [2293, 2791], [2297, 2762], [2287, 2760], [2281, 2766], [2283, 2760], [2272, 2748], [2268, 2747], [2269, 2740], [2276, 2733], [2257, 2726], [2249, 2713], [2240, 2709], [2231, 2689], [2304, 2688], [2232, 2688], [2236, 2684], [2222, 2685], [2215, 2688], [2195, 2703], [2190, 2723], [2186, 2726], [2181, 2723], [2169, 2725], [2159, 2740], [2167, 2763], [2162, 2769], [2155, 2766], [2148, 2770], [2146, 2779], [2149, 2788], [2140, 2799], [2139, 2800], [2149, 2812], [2152, 2823], [2147, 2828], [2149, 2835], [2147, 2839], [2136, 2844], [2137, 2859], [2155, 2895], [2176, 2913], [2193, 2947], [2216, 2955], [2232, 2968], [2242, 2967], [2250, 2958], [2258, 2934], [2255, 2931], [2253, 2920], [2261, 2910], [2275, 2923], [2280, 2939], [2268, 2939], [2271, 2941], [2284, 2939], [2304, 2929], [2348, 2916], [2349, 2913], [2362, 2904], [2371, 2905], [2377, 2903], [2377, 2910], [2384, 2920], [2380, 2920], [2373, 2910], [2368, 2912], [2367, 2921], [2383, 2938], [2391, 2940], [2395, 2936], [2399, 2924], [2406, 2929], [2411, 2923], [2414, 2927], [2437, 2923], [2444, 2914], [2438, 2904], [2432, 2905], [2414, 2894], [2401, 2892], [2379, 2850], [2374, 2832], [2373, 2816], [2370, 2807], [2375, 2799], [2368, 2798], [2365, 2794], [2374, 2796], [2379, 2789], [2372, 2786], [2368, 2789], [2365, 2786], [2371, 2783], [2382, 2787], [2386, 2785], [2382, 2776], [2386, 2772], [2390, 2775], [2399, 2772], [2401, 2775], [2409, 2774], [2415, 2778], [2418, 2789], [2410, 2803], [2392, 2823], [2394, 2827], [2391, 2844], [2401, 2852], [2401, 2864], [2407, 2866], [2409, 2880], [2415, 2881], [2416, 2886], [2421, 2886], [2429, 2896], [2440, 2893], [2452, 2894], [2455, 2903], [2475, 2895], [2491, 2879], [2493, 2863], [2499, 2857], [2495, 2852], [2493, 2838], [2496, 2828], [2510, 2816], [2521, 2816], [2515, 2803], [2495, 2790], [2489, 2780], [2475, 2777], [2461, 2761], [2445, 2752], [2432, 2752], [2427, 2756], [2430, 2759], [2418, 2761], [2393, 2749], [2358, 2703], [2347, 2698], [2340, 2691], [2342, 2700], [2348, 2711], [2347, 2716], [2353, 2721], [2355, 2728], [2347, 2720], [2331, 2712], [2321, 2717], [2318, 2735], [2320, 2750], [2317, 2776], [2327, 2786], [2328, 2790], [2319, 2798], [2308, 2797]], [[2601, 2904], [2625, 2913], [2645, 2940], [2651, 2944], [2672, 2951], [2688, 2952], [2711, 2949], [2733, 2937], [2760, 2929], [2762, 2912], [2761, 2906], [2774, 2882], [2771, 2879], [2763, 2882], [2764, 2886], [2755, 2891], [2745, 2880], [2744, 2875], [2737, 2869], [2719, 2865], [2703, 2858], [2692, 2862], [2683, 2868], [2671, 2871], [2665, 2867], [2663, 2849], [2666, 2840], [2657, 2833], [2640, 2835], [2622, 2826], [2618, 2831], [2609, 2831], [2610, 2832], [2600, 2842], [2610, 2838], [2615, 2847], [2608, 2842], [2601, 2848], [2596, 2848], [2584, 2842], [2578, 2827], [2578, 2821], [2583, 2816], [2580, 2807], [2571, 2799], [2566, 2807], [2568, 2816], [2565, 2827], [2560, 2833], [2561, 2846], [2558, 2860], [2554, 2862], [2560, 2872], [2583, 2886], [2601, 2904]], [[2104, 2793], [2094, 2785], [2089, 2777], [2081, 2747], [2079, 2753], [2081, 2759], [2075, 2784], [2077, 2798], [2075, 2816], [2070, 2826], [2071, 2837], [2080, 2840], [2088, 2838], [2096, 2826], [2092, 2816], [2098, 2801], [2104, 2793]], [[2076, 3038], [2068, 3035], [2069, 3051], [2079, 3058], [2085, 3072], [2095, 3082], [2097, 3090], [2102, 3095], [2107, 3089], [2106, 3078], [2100, 3072], [2096, 3062], [2076, 3038]], [[1790, 3235], [1792, 3238], [1794, 3230], [1790, 3235]], [[1787, 3236], [1781, 3235], [1783, 3240], [1787, 3236]], [[2285, 3040], [2283, 3060], [2286, 3072], [2293, 3087], [2297, 3089], [2304, 3087], [2320, 3078], [2323, 3072], [2323, 3057], [2326, 3044], [2324, 3037], [2316, 3031], [2304, 3031], [2291, 3034], [2285, 3040]], [[2434, 3176], [2438, 3164], [2422, 3137], [2404, 3119], [2395, 3107], [2388, 3102], [2378, 3099], [2369, 3090], [2350, 3095], [2335, 3103], [2329, 3098], [2325, 3101], [2318, 3112], [2312, 3140], [2304, 3154], [2292, 3166], [2270, 3167], [2265, 3172], [2269, 3181], [2275, 3182], [2293, 3171], [2304, 3168], [2304, 3200], [2305, 3168], [2316, 3170], [2334, 3182], [2350, 3190], [2382, 3197], [2387, 3200], [2397, 3199], [2424, 3207], [2432, 3203], [2440, 3203], [2438, 3200], [2437, 3200], [2434, 3176]], [[2204, 3412], [2209, 3408], [2216, 3409], [2206, 3403], [2200, 3410], [2204, 3412]], [[2212, 3429], [2204, 3434], [2208, 3438], [2215, 3437], [2225, 3431], [2212, 3429]], [[1577, 3091], [1569, 3091], [1561, 3098], [1567, 3104], [1574, 3101], [1578, 3101], [1577, 3091]], [[1553, 3108], [1547, 3112], [1552, 3114], [1553, 3108]], [[1553, 3120], [1549, 3127], [1552, 3127], [1553, 3120]], [[1549, 3128], [1549, 3127], [1548, 3116], [1546, 3116], [1546, 3131], [1549, 3128]], [[1629, 3141], [1633, 3133], [1630, 3132], [1629, 3141]], [[1627, 3152], [1629, 3141], [1624, 3150], [1627, 3152]], [[1633, 3155], [1627, 3152], [1629, 3159], [1633, 3155]], [[1512, 3140], [1520, 3121], [1515, 3125], [1512, 3140]], [[1713, 3159], [1721, 3160], [1723, 3156], [1714, 3152], [1713, 3159]], [[1731, 3166], [1728, 3163], [1724, 3169], [1731, 3166]], [[1309, 3176], [1307, 3169], [1305, 3174], [1309, 3176]], [[1311, 3178], [1304, 3183], [1310, 3185], [1311, 3178]], [[1363, 3220], [1368, 3217], [1369, 3211], [1364, 3213], [1363, 3220]], [[1356, 3213], [1350, 3219], [1357, 3224], [1356, 3213]], [[1344, 3220], [1340, 3224], [1347, 3224], [1344, 3220]], [[1745, 3286], [1745, 3290], [1752, 3286], [1750, 3281], [1743, 3280], [1728, 3283], [1724, 3289], [1732, 3290], [1732, 3293], [1745, 3286]], [[1721, 3287], [1728, 3283], [1741, 3277], [1751, 3276], [1752, 3281], [1762, 3284], [1764, 3283], [1768, 3286], [1769, 3282], [1775, 3278], [1764, 3276], [1749, 3269], [1731, 3276], [1725, 3274], [1721, 3287]], [[1776, 3286], [1768, 3286], [1777, 3290], [1776, 3286]], [[1788, 3292], [1776, 3286], [1782, 3292], [1788, 3292]], [[1712, 3285], [1703, 3285], [1701, 3291], [1707, 3291], [1712, 3285]], [[1754, 3294], [1752, 3289], [1744, 3292], [1734, 3293], [1749, 3303], [1748, 3298], [1753, 3303], [1756, 3300], [1769, 3304], [1769, 3302], [1756, 3297], [1754, 3294]], [[1720, 3307], [1731, 3303], [1734, 3298], [1729, 3294], [1727, 3299], [1720, 3307]], [[1738, 3300], [1731, 3303], [1723, 3307], [1732, 3307], [1738, 3300]], [[1716, 3301], [1712, 3297], [1706, 3305], [1710, 3301], [1716, 3301]], [[1718, 3299], [1717, 3303], [1723, 3302], [1725, 3299], [1718, 3299]], [[1686, 3308], [1691, 3311], [1699, 3308], [1707, 3301], [1702, 3302], [1693, 3300], [1686, 3308]], [[1713, 3306], [1715, 3312], [1720, 3305], [1713, 3306]], [[1685, 3310], [1685, 3304], [1672, 3313], [1671, 3319], [1674, 3322], [1689, 3324], [1684, 3320], [1695, 3312], [1697, 3310], [1691, 3312], [1685, 3310]], [[1705, 3318], [1695, 3312], [1692, 3319], [1700, 3321], [1705, 3318]], [[1690, 3319], [1684, 3320], [1694, 3323], [1690, 3319]], [[1710, 3317], [1704, 3320], [1712, 3321], [1710, 3317]], [[1783, 3318], [1762, 3319], [1737, 3304], [1732, 3308], [1720, 3309], [1712, 3317], [1728, 3328], [1737, 3328], [1753, 3333], [1757, 3336], [1768, 3337], [1764, 3328], [1770, 3336], [1781, 3332], [1776, 3328], [1787, 3327], [1789, 3323], [1792, 3328], [1795, 3325], [1783, 3318]], [[1733, 3335], [1726, 3332], [1729, 3337], [1733, 3335]], [[1736, 3347], [1747, 3350], [1746, 3343], [1733, 3336], [1730, 3338], [1736, 3347]], [[1746, 3341], [1746, 3343], [1748, 3349], [1756, 3351], [1762, 3356], [1770, 3352], [1775, 3357], [1776, 3357], [1783, 3360], [1792, 3367], [1792, 3358], [1799, 3355], [1792, 3352], [1794, 3343], [1797, 3342], [1779, 3336], [1761, 3343], [1768, 3338], [1758, 3338], [1742, 3331], [1732, 3331], [1746, 3341]], [[1788, 3334], [1779, 3336], [1792, 3337], [1788, 3334]], [[1796, 3366], [1792, 3367], [1786, 3369], [1774, 3364], [1768, 3365], [1772, 3377], [1775, 3375], [1792, 3375], [1799, 3368], [1796, 3366]], [[1788, 3328], [1783, 3334], [1795, 3332], [1788, 3328]], [[1761, 3369], [1752, 3364], [1758, 3370], [1761, 3369]], [[1800, 3242], [1792, 3241], [1792, 3245], [1800, 3242]], [[1781, 3253], [1787, 3250], [1773, 3247], [1764, 3253], [1781, 3253]], [[1773, 3273], [1767, 3270], [1762, 3272], [1773, 3273]], [[1768, 3276], [1772, 3274], [1762, 3273], [1768, 3276]], [[1792, 3285], [1792, 3283], [1778, 3283], [1774, 3283], [1792, 3287], [1792, 3285]], [[1770, 3291], [1758, 3286], [1756, 3292], [1770, 3300], [1779, 3300], [1771, 3295], [1770, 3291]], [[1760, 3311], [1766, 3310], [1757, 3304], [1760, 3311]], [[1764, 3385], [1775, 3387], [1761, 3381], [1764, 3385]], [[1771, 3392], [1764, 3385], [1759, 3385], [1767, 3393], [1771, 3392]], [[1768, 3397], [1756, 3385], [1760, 3399], [1766, 3398], [1768, 3397]], [[1822, 3449], [1818, 3444], [1822, 3456], [1822, 3449]], [[2153, 3448], [2141, 3456], [2154, 3463], [2155, 3460], [2167, 3463], [2171, 3472], [2176, 3471], [2182, 3465], [2186, 3456], [2184, 3449], [2176, 3446], [2172, 3450], [2166, 3447], [2153, 3448]], [[2795, 3479], [2783, 3476], [2797, 3482], [2795, 3479]], [[2175, 3490], [2169, 3495], [2173, 3499], [2175, 3490]], [[3255, 3546], [3254, 3540], [3251, 3546], [3255, 3546]], [[3218, 3558], [3217, 3547], [3206, 3543], [3211, 3547], [3209, 3557], [3218, 3558]], [[3256, 3556], [3254, 3562], [3258, 3563], [3263, 3570], [3261, 3562], [3263, 3559], [3256, 3556]], [[3288, 3579], [3294, 3583], [3300, 3580], [3288, 3579]], [[3615, 3684], [3610, 3678], [3604, 3675], [3615, 3684]], [[3584, 3673], [3566, 3666], [3561, 3666], [3548, 3677], [3540, 3692], [3554, 3700], [3557, 3709], [3584, 3723], [3604, 3725], [3609, 3712], [3608, 3699], [3614, 3699], [3615, 3686], [3584, 3673]], [[3650, 3696], [3641, 3702], [3646, 3706], [3650, 3696]]] \ No newline at end of file diff --git a/test/test.js b/test/test.js index d04ff48..98d1773 100644 --- a/test/test.js +++ b/test/test.js @@ -22,20 +22,39 @@ test('empty', () => { for (const id of Object.keys(expected.triangles)) { - test(id, () => { - const data = flatten(JSON.parse(fs.readFileSync(new URL(`fixtures/${id}.json`, import.meta.url)))), - indices = earcut(data.vertices, data.holes, data.dimensions), - err = deviation(data.vertices, data.holes, data.dimensions, indices), - expectedTriangles = expected.triangles[id], - expectedDeviation = expected.errors[id] || 0; - - const numTriangles = indices.length / 3; - assert.ok(numTriangles === expectedTriangles, `${numTriangles} triangles when expected ${expectedTriangles}`); - - if (expectedTriangles > 0) { - assert.ok(err <= expectedDeviation, `deviation ${err} <= ${expectedDeviation}`); - } - }); + for (const rotation of [0, 90, 180, 270]) { + test(`${id} rotation ${rotation}`, () => { + const coords = JSON.parse(fs.readFileSync(new URL(`fixtures/${id}.json`, import.meta.url))); + const theta = rotation * Math.PI / 180; + const xx = Math.round(Math.cos(theta)); + const xy = Math.round(-Math.sin(theta)); + const yx = Math.round(Math.sin(theta)); + const yy = Math.round(Math.cos(theta)); + if (rotation) { + for (const ring of coords) { + for (const coord of ring) { + const [x, y] = coord; + coord[0] = xx * x + xy * y; + coord[1] = yx * x + yy * y; + } + } + } + const data = flatten(coords), + indices = earcut(data.vertices, data.holes, data.dimensions), + err = deviation(data.vertices, data.holes, data.dimensions, indices), + expectedTriangles = expected.triangles[id], + expectedDeviation = (rotation !== 0 && expected['errors-with-rotation'][id]) || expected.errors[id] || 0; + + const numTriangles = indices.length / 3; + if (rotation === 0) { + assert.ok(numTriangles === expectedTriangles, `${numTriangles} triangles when expected ${expectedTriangles}`); + } + + if (expectedTriangles > 0) { + assert.ok(err <= expectedDeviation, `deviation ${err} <= ${expectedDeviation}`); + } + }); + } } test('infinite-loop', () => { diff --git a/viz/viz.js b/viz/viz.js index 34c7678..e44346d 100644 --- a/viz/viz.js +++ b/viz/viz.js @@ -2,125 +2,132 @@ import earcut, {flatten, deviation} from '../src/earcut.js'; -const testPoints = [ - [[2293,4224],[2294,4219],[2280,4180],[2288,4172],[2283,4189],[2301,4218],[2299,4224],[2347,4224],[2344,4215],[2351,4224],[2371,4224],[2379,4224],[2375,4206],[2363,4202],[2346,4194],[2371,4195],[2376,4180],[2383,4202],[2429,4176],[2431,4163],[2439,4161],[2438,4144],[2464,4124],[2457,4111],[2467,4102],[2473,4060],[2482,4053],[2488,4031],[2467,3982],[2456,3991],[2456,4005],[2451,3998],[2451,4014],[2432,4011],[2433,4025],[2427,4012],[2415,4009],[2438,4003],[2419,3990],[2411,3987],[2391,4000],[2391,3989],[2374,3991],[2382,3995],[2363,4028],[2364,4042],[2380,4041],[2389,4029],[2387,4053],[2412,4055],[2376,4059],[2389,4085],[2381,4093],[2371,4076],[2363,4082],[2372,4067],[2362,4059],[2347,4054],[2349,4040],[2344,4057],[2325,4063],[2322,4073],[2332,4078],[2325,4086],[2317,4082],[2308,4065],[2321,4063],[2299,4051],[2312,4056],[2326,4055],[2325,4044],[2302,4021],[2315,4029],[2324,4023],[2333,4040],[2335,4026],[2349,4016],[2333,3999],[2318,4002],[2333,3991],[2321,3985],[2350,4000],[2350,3962],[2331,3964],[2340,3949],[2332,3946],[2341,3943],[2345,3952],[2358,3947],[2350,3922],[2362,3931],[2363,3922],[2368,3946],[2377,3946],[2388,3933],[2378,3908],[2389,3920],[2393,3948],[2401,3924],[2400,3911],[2382,3899],[2388,3875],[2366,3885],[2350,3878],[2340,3896],[2327,3880],[2323,3900],[2313,3894],[2300,3871],[2307,3890],[2331,3872],[2317,3867],[2345,3852],[2343,3840],[2351,3843],[2348,3823],[2339,3821],[2341,3805],[2350,3828],[2379,3853],[2385,3844],[2368,3823],[2370,3809],[2362,3809],[2361,3793],[2372,3804],[2379,3795],[2376,3823],[2388,3815],[2402,3822],[2393,3832],[2384,3824],[2404,3860],[2407,3876],[2416,3872],[2418,3852],[2427,3876],[2409,3893],[2429,3921],[2484,3863],[2478,3792],[2440,3820],[2439,3834],[2438,3820],[2426,3809],[2435,3801],[2421,3794],[2429,3786],[2406,3752],[2424,3748],[2440,3762],[2431,3732],[2415,3735],[2412,3721],[2391,3707],[2381,3720],[2382,3732],[2370,3724],[2382,3716],[2372,3705],[2380,3708],[2378,3687],[2368,3685],[2349,3710],[2338,3694],[2337,3708],[2324,3706],[2327,3717],[2316,3729],[2323,3715],[2309,3714],[2318,3713],[2311,3699],[2332,3698],[2334,3678],[2356,3670],[2343,3651],[2332,3649],[2335,3658],[2324,3655],[2323,3670],[2324,3661],[2311,3661],[2332,3640],[2316,3633],[2286,3655],[2302,3631],[2277,3610],[2269,3619],[2250,3619],[2250,3630],[2239,3635],[2244,3650],[2228,3660],[2236,3679],[2226,3666],[2207,3677],[2199,3672],[2235,3648],[2232,3621],[2240,3624],[2249,3605],[2229,3607],[2219,3593],[2209,3597],[2218,3587],[2202,3586],[2201,3576],[2180,3583],[2177,3598],[2178,3573],[2165,3548],[2153,3544],[2148,3519],[2154,3506],[2139,3492],[2141,3484],[2149,3492],[2186,3568],[2207,3567],[2233,3585],[2231,3533],[2248,3519],[2248,3532],[2238,3536],[2247,3547],[2238,3549],[2237,3574],[2260,3602],[2261,3586],[2272,3598],[2294,3599],[2288,3559],[2300,3578],[2303,3610],[2324,3615],[2341,3612],[2342,3596],[2330,3591],[2342,3588],[2346,3561],[2348,3612],[2363,3604],[2365,3582],[2374,3590],[2376,3576],[2386,3591],[2403,3596],[2387,3598],[2370,3598],[2364,3636],[2379,3621],[2387,3653],[2400,3620],[2414,3623],[2402,3632],[2397,3650],[2411,3667],[2410,3682],[2427,3678],[2420,3667],[2425,3649],[2443,3653],[2426,3651],[2433,3664],[2429,3672],[2440,3671],[2440,3681],[2426,3688],[2454,3700],[2457,3689],[2462,3698],[2456,3717],[2499,3696],[2488,3686],[2498,3690],[2499,3682],[2520,3700],[2503,3702],[2499,3713],[2510,3706],[2518,3708],[2513,3730],[2530,3746],[2521,3746],[2546,3760],[2549,3777],[2574,3779],[2550,3768],[2536,3721],[2551,3725],[2555,3750],[2578,3746],[2564,3704],[2554,3709],[2542,3694],[2563,3704],[2571,3682],[2602,3652],[2577,3623],[2568,3629],[2581,3639],[2576,3655],[2561,3636],[2560,3648],[2549,3634],[2524,3637],[2531,3625],[2564,3627],[2537,3582],[2530,3591],[2534,3554],[2522,3558],[2519,3574],[2506,3576],[2504,3595],[2493,3598],[2502,3592],[2505,3572],[2513,3563],[2502,3559],[2517,3548],[2527,3551],[2533,3539],[2518,3523],[2503,3538],[2485,3535],[2479,3545],[2478,3535],[2467,3540],[2466,3555],[2454,3547],[2443,3562],[2450,3547],[2437,3543],[2462,3542],[2459,3532],[2470,3535],[2477,3525],[2500,3530],[2496,3515],[2515,3515],[2527,3502],[2503,3482],[2481,3486],[2453,3506],[2462,3496],[2461,3485],[2496,3481],[2490,3464],[2467,3463],[2479,3445],[2458,3437],[2430,3471],[2391,3471],[2403,3470],[2410,3460],[2428,3464],[2450,3428],[2435,3418],[2426,3429],[2437,3412],[2418,3406],[2415,3415],[2388,3419],[2411,3403],[2395,3399],[2404,3392],[2385,3384],[2366,3406],[2347,3410],[2384,3376],[2370,3365],[2347,3376],[2327,3371],[2376,3358],[2372,3347],[2357,3342],[2331,3350],[2334,3342],[2361,3335],[2363,3326],[2321,3317],[2303,3328],[2312,3311],[2320,3316],[2270,3302],[2257,3308],[2263,3321],[2248,3330],[2257,3316],[2246,3300],[2238,3323],[2227,3318],[2227,3304],[2243,3294],[2253,3297],[2249,3282],[2232,3278],[2242,3274],[2242,3266],[2258,3264],[2257,3255],[2269,3248],[2292,3263],[2278,3245],[2259,3239],[2278,3244],[2281,3231],[2266,3217],[2252,3217],[2250,3196],[2228,3218],[2220,3219],[2237,3199],[2215,3194],[2243,3196],[2237,3177],[2209,3171],[2189,3154],[2157,3144],[2144,3152],[2151,3141],[2139,3130],[2122,3148],[2113,3127],[2125,3142],[2130,3117],[2147,3119],[2149,3128],[2167,3120],[2169,3146],[2187,3143],[2212,3166],[2224,3161],[2225,3173],[2243,3145],[2244,3156],[2235,3162],[2254,3175],[2272,3176],[2289,3165],[2286,3182],[2274,3178],[2268,3195],[2304,3196],[2310,3180],[2323,3209],[2339,3214],[2349,3249],[2359,3249],[2357,3295],[2359,3287],[2385,3284],[2368,3300],[2393,3315],[2388,3339],[2401,3357],[2414,3352],[2410,3342],[2422,3334],[2417,3348],[2435,3354],[2416,3357],[2420,3376],[2436,3385],[2452,3381],[2444,3384],[2447,3396],[2466,3394],[2479,3417],[2490,3400],[2499,3452],[2529,3469],[2531,3481],[2547,3497],[2554,3488],[2565,3503],[2579,3490],[2569,3465],[2591,3499],[2589,3527],[2600,3518],[2606,3498],[2604,3456],[2589,3465],[2591,3456],[2572,3442],[2583,3440],[2582,3430],[2571,3419],[2557,3420],[2570,3415],[2580,3423],[2580,3409],[2530,3373],[2587,3402],[2595,3447],[2604,3413],[2598,3436],[2609,3432],[2601,3446],[2614,3451],[2635,3442],[2644,3447],[2655,3434],[2646,3429],[2646,3411],[2632,3413],[2650,3405],[2646,3393],[2610,3389],[2619,3383],[2603,3373],[2616,3372],[2623,3384],[2646,3388],[2650,3359],[2612,3347],[2641,3355],[2643,3345],[2654,3359],[2648,3382],[2662,3381],[2654,3413],[2659,3426],[2673,3429],[2673,3417],[2685,3418],[2679,3396],[2695,3397],[2684,3405],[2693,3416],[2686,3425],[2676,3422],[2684,3439],[2669,3471],[2676,3482],[2688,3472],[2684,3453],[2711,3444],[2698,3444],[2710,3426],[2702,3424],[2716,3422],[2737,3403],[2731,3374],[2746,3381],[2744,3399],[2765,3387],[2745,3326],[2735,3313],[2715,3318],[2724,3314],[2739,3307],[2666,3259],[2658,3286],[2668,3292],[2656,3294],[2655,3312],[2642,3304],[2656,3286],[2645,3286],[2653,3278],[2644,3273],[2662,3259],[2637,3234],[2591,3240],[2555,3270],[2578,3246],[2574,3238],[2585,3239],[2596,3228],[2583,3210],[2576,3218],[2580,3208],[2545,3209],[2529,3198],[2517,3209],[2513,3182],[2491,3203],[2495,3222],[2488,3230],[2483,3213],[2491,3208],[2476,3207],[2486,3201],[2483,3187],[2471,3185],[2460,3193],[2466,3183],[2452,3158],[2426,3163],[2418,3175],[2434,3195],[2435,3211],[2424,3200],[2426,3185],[2413,3177],[2403,3190],[2405,3205],[2395,3210],[2398,3198],[2383,3205],[2384,3194],[2400,3195],[2414,3172],[2393,3157],[2362,3192],[2364,3183],[2356,3180],[2371,3170],[2364,3166],[2379,3166],[2360,3150],[2394,3153],[2398,3135],[2401,3147],[2408,3128],[2395,3126],[2386,3114],[2377,3117],[2371,3106],[2351,3105],[2343,3109],[2360,3098],[2380,3105],[2376,3090],[2355,3081],[2362,3073],[2358,3041],[2339,3025],[2334,3010],[2314,3000],[2335,3006],[2349,3032],[2359,3025],[2370,3073],[2384,3089],[2388,3072],[2411,3063],[2422,3047],[2417,3063],[2394,3072],[2384,3101],[2400,3113],[2418,3094],[2412,3108],[2423,3106],[2426,3117],[2446,3119],[2446,3141],[2466,3128],[2456,3108],[2460,3097],[2471,3117],[2487,3107],[2470,3122],[2479,3137],[2485,3127],[2499,3130],[2506,3106],[2528,3101],[2529,3109],[2515,3113],[2529,3135],[2526,3114],[2541,3130],[2558,3114],[2561,3101],[2548,3102],[2535,3087],[2555,3094],[2544,3073],[2562,3099],[2576,3101],[2585,3096],[2580,3079],[2588,3073],[2605,3065],[2615,3073],[2632,3084],[2628,3071],[2620,3067],[2600,3039],[2612,3046],[2634,3071],[2642,3082],[2646,3073],[2646,3083],[2672,3093],[2677,3106],[2670,3071],[2652,3011],[2659,2936],[2636,2937],[2629,2961],[2636,2973],[2617,2976],[2629,2992],[2618,2988],[2599,2996],[2613,2989],[2613,2967],[2604,2973],[2609,2958],[2598,2962],[2586,2962],[2583,2975],[2581,2965],[2565,2975],[2574,2963],[2537,2964],[2536,2984],[2535,2961],[2512,2973],[2501,2962],[2531,2959],[2530,2951],[2538,2957],[2553,2954],[2578,2954],[2604,2944],[2618,2953],[2610,2939],[2574,2946],[2541,2926],[2576,2938],[2618,2927],[2634,2921],[2552,2863],[2521,2805],[2498,2823],[2494,2838],[2503,2847],[2493,2842],[2455,2853],[2485,2877],[2459,2862],[2443,2871],[2449,2888],[2429,2873],[2430,2861],[2416,2880],[2421,2900],[2408,2887],[2388,2915],[2420,2868],[2412,2855],[2441,2851],[2455,2834],[2447,2809],[2421,2784],[2423,2796],[2395,2818],[2400,2827],[2387,2823],[2384,2844],[2376,2841],[2367,2847],[2371,2858],[2348,2865],[2347,2879],[2325,2871],[2326,2891],[2308,2884],[2298,2898],[2297,2888],[2283,2893],[2283,2884],[2312,2880],[2294,2859],[2316,2872],[2315,2862],[2349,2857],[2333,2848],[2360,2850],[2358,2840],[2369,2834],[2339,2821],[2309,2824],[2310,2815],[2328,2816],[2342,2814],[2340,2804],[2357,2819],[2360,2798],[2365,2818],[2379,2820],[2391,2793],[2409,2789],[2392,2771],[2392,2782],[2384,2779],[2370,2792],[2368,2783],[2356,2785],[2366,2775],[2375,2783],[2373,2774],[2389,2773],[2360,2717],[2360,2707],[2377,2698],[2356,2669],[2364,2645],[2355,2642],[2360,2633],[2339,2644],[2342,2629],[2324,2645],[2312,2639],[2310,2616],[2275,2627],[2229,2610],[2219,2563],[2234,2585],[2252,2578],[2270,2589],[2286,2553],[2266,2527],[2255,2528],[2235,2496],[2221,2505],[2230,2489],[2220,2497],[2225,2486],[2210,2479],[2185,2482],[2190,2517],[2171,2513],[2171,2500],[2162,2517],[2144,2518],[2121,2472],[2096,2474],[2076,2458],[2094,2427],[2087,2410],[2095,2408],[2104,2408],[2105,2444],[2126,2453],[2136,2471],[2152,2458],[2142,2448],[2159,2433],[2196,2452],[2216,2442],[2225,2451],[2232,2441],[2223,2420],[2217,2428],[2223,2416],[2215,2425],[2219,2412],[2210,2420],[2213,2409],[2207,2417],[2197,2397],[2170,2407],[2154,2398],[2150,2376],[2132,2372],[2132,2360],[2143,2364],[2143,2356],[2158,2373],[2176,2372],[2166,2375],[2167,2385],[2192,2374],[2202,2384],[2199,2373],[2208,2368],[2225,2380],[2228,2392],[2250,2393],[2253,2411],[2257,2423],[2246,2426],[2257,2428],[2246,2431],[2257,2438],[2248,2447],[2257,2459],[2268,2456],[2269,2469],[2276,2452],[2286,2468],[2285,2451],[2294,2450],[2295,2465],[2304,2453],[2304,2464],[2340,2491],[2352,2462],[2339,2446],[2342,2433],[2357,2470],[2345,2510],[2362,2534],[2389,2522],[2408,2524],[2409,2559],[2418,2574],[2398,2596],[2450,2560],[2456,2541],[2445,2541],[2461,2531],[2440,2529],[2437,2519],[2467,2522],[2474,2513],[2460,2501],[2437,2505],[2447,2498],[2433,2476],[2447,2493],[2439,2469],[2449,2475],[2456,2497],[2462,2489],[2477,2501],[2489,2493],[2488,2485],[2468,2477],[2473,2460],[2461,2455],[2462,2446],[2486,2477],[2507,2485],[2509,2472],[2518,2469],[2505,2458],[2514,2462],[2522,2451],[2512,2414],[2493,2409],[2505,2409],[2516,2401],[2517,2412],[2533,2405],[2519,2414],[2522,2438],[2554,2449],[2525,2453],[2527,2462],[2541,2463],[2529,2465],[2524,2475],[2542,2492],[2521,2481],[2517,2490],[2527,2501],[2492,2499],[2494,2516],[2475,2543],[2487,2578],[2466,2581],[2461,2594],[2470,2601],[2458,2602],[2471,2608],[2458,2609],[2470,2612],[2468,2625],[2455,2633],[2475,2634],[2454,2640],[2456,2652],[2468,2652],[2462,2661],[2481,2677],[2481,2671],[2499,2671],[2501,2639],[2527,2635],[2513,2645],[2511,2676],[2515,2664],[2565,2659],[2565,2614],[2563,2589],[2571,2569],[2587,2575],[2604,2570],[2572,2584],[2572,2592],[2587,2588],[2584,2594],[2594,2594],[2578,2606],[2594,2613],[2626,2608],[2630,2590],[2619,2589],[2633,2586],[2634,2572],[2642,2572],[2638,2598],[2635,2613],[2642,2605],[2618,2624],[2622,2642],[2604,2675],[2611,2691],[2626,2699],[2643,2671],[2620,2670],[2642,2663],[2624,2659],[2628,2645],[2640,2649],[2635,2637],[2645,2638],[2653,2625],[2660,2639],[2647,2655],[2655,2662],[2676,2660],[2684,2667],[2676,2657],[2698,2605],[2754,2571],[2743,2564],[2753,2537],[2723,2564],[2687,2563],[2673,2544],[2627,2520],[2633,2509],[2617,2501],[2613,2511],[2594,2512],[2615,2487],[2591,2457],[2597,2444],[2587,2421],[2599,2423],[2602,2413],[2570,2381],[2538,2365],[2525,2340],[2498,2347],[2511,2334],[2508,2322],[2495,2321],[2485,2302],[2459,2293],[2458,2281],[2468,2271],[2483,2280],[2486,2262],[2498,2265],[2487,2288],[2503,2296],[2517,2291],[2528,2304],[2551,2311],[2558,2335],[2562,2313],[2552,2307],[2548,2290],[2562,2302],[2567,2322],[2591,2296],[2574,2321],[2565,2332],[2589,2352],[2601,2338],[2593,2353],[2600,2361],[2636,2366],[2638,2355],[2646,2352],[2643,2336],[2651,2352],[2658,2343],[2653,2354],[2661,2363],[2644,2361],[2642,2371],[2651,2375],[2635,2374],[2639,2413],[2650,2416],[2631,2451],[2641,2454],[2642,2479],[2671,2475],[2702,2501],[2717,2497],[2726,2504],[2731,2491],[2721,2477],[2735,2496],[2746,2498],[2734,2473],[2764,2425],[2742,2435],[2741,2419],[2752,2418],[2756,2407],[2743,2403],[2756,2396],[2745,2389],[2756,2389],[2761,2380],[2763,2397],[2787,2379],[2794,2397],[2800,2387],[2792,2370],[2803,2363],[2795,2356],[2764,2357],[2762,2344],[2761,2363],[2753,2361],[2742,2372],[2750,2359],[2741,2357],[2715,2378],[2719,2360],[2702,2371],[2709,2361],[2695,2343],[2713,2354],[2722,2350],[2714,2327],[2722,2329],[2731,2352],[2740,2346],[2732,2334],[2750,2346],[2752,2318],[2744,2320],[2736,2307],[2723,2306],[2725,2316],[2723,2301],[2714,2290],[2710,2304],[2702,2304],[2702,2313],[2693,2318],[2685,2320],[2686,2310],[2704,2299],[2703,2289],[2683,2300],[2675,2294],[2673,2303],[2665,2298],[2653,2304],[2662,2298],[2657,2289],[2669,2293],[2668,2283],[2678,2289],[2677,2277],[2683,2285],[2694,2282],[2693,2266],[2677,2264],[2675,2254],[2653,2260],[2654,2270],[2642,2269],[2647,2259],[2635,2266],[2620,2242],[2636,2256],[2652,2253],[2629,2228],[2623,2204],[2645,2235],[2669,2245],[2658,2225],[2646,2205],[2660,2213],[2677,2198],[2668,2223],[2680,2227],[2677,2236],[2717,2275],[2695,2228],[2713,2238],[2722,2259],[2737,2242],[2740,2218],[2722,2199],[2719,2182],[2727,2191],[2730,2177],[2742,2169],[2733,2198],[2738,2208],[2744,2188],[2756,2187],[2748,2188],[2743,2208],[2755,2209],[2747,2236],[2750,2247],[2760,2245],[2743,2262],[2742,2274],[2755,2270],[2766,2291],[2770,2261],[2783,2253],[2783,2274],[2797,2272],[2797,2262],[2806,2267],[2808,2290],[2796,2294],[2795,2305],[2809,2309],[2833,2291],[2851,2258],[2836,2266],[2826,2257],[2845,2248],[2833,2244],[2833,2235],[2813,2245],[2805,2227],[2787,2242],[2773,2224],[2789,2229],[2797,2219],[2781,2202],[2798,2214],[2808,2209],[2809,2220],[2825,2230],[2834,2227],[2830,2215],[2839,2207],[2840,2218],[2849,2223],[2860,2203],[2848,2185],[2836,2195],[2819,2192],[2836,2189],[2837,2179],[2825,2164],[2824,2156],[2794,2148],[2799,2140],[2790,2130],[2813,2149],[2822,2147],[2821,2133],[2835,2159],[2877,2174],[2870,2160],[2875,2149],[2856,2150],[2846,2131],[2838,2134],[2829,2109],[2841,2122],[2848,2110],[2858,2117],[2865,2103],[2851,2093],[2860,2092],[2858,2083],[2869,2100],[2867,2110],[2876,2110],[2868,2121],[2874,2135],[2886,2133],[2895,2116],[2890,2138],[2896,2157],[2909,2148],[2932,2155],[2940,2177],[2952,2172],[2908,2089],[2923,2075],[2923,2049],[2929,2028],[2895,2023],[2885,2002],[2871,1999],[2861,2014],[2837,2011],[2832,2021],[2851,2042],[2828,2033],[2831,2049],[2828,2049],[2814,2049],[2826,2029],[2811,2019],[2795,2032],[2801,2018],[2755,2011],[2757,1995],[2749,1996],[2750,2007],[2732,2008],[2733,1998],[2704,1994],[2715,1985],[2695,1987],[2713,1981],[2753,1987],[2772,2002],[2788,1999],[2788,1988],[2792,2001],[2828,1999],[2856,1952],[2837,1954],[2828,1933],[2815,1928],[2860,1933],[2854,1971],[2863,1959],[2872,1966],[2874,1936],[2882,1933],[2892,1956],[2896,1943],[2905,1942],[2911,1961],[2954,1975],[2966,1967],[2992,1968],[3021,1984],[3036,2021],[3030,2047],[3022,2078],[2973,2093],[3007,2095],[3051,2113],[3055,2128],[3044,2153],[3043,2189],[3066,2238],[3069,2269],[3049,2299],[3073,2303],[3094,2306],[3103,2225],[3136,2196],[3135,2188],[3126,2194],[3168,2163],[3157,2149],[3163,2130],[3141,2120],[3137,2109],[3141,2083],[3120,2077],[3119,2109],[3115,2078],[3104,2078],[3115,2074],[3112,2064],[3088,2062],[3078,2047],[3083,2035],[3092,2042],[3094,2033],[3106,2038],[3122,2017],[3115,2006],[3103,2008],[3105,1998],[3132,1971],[3125,1979],[3107,1972],[3107,1956],[3093,1963],[3081,1966],[3101,1952],[3089,1939],[3101,1935],[3121,1953],[3124,1964],[3142,1956],[3131,1919],[3111,1905],[3105,1918],[3103,1908],[3086,1912],[3099,1897],[3092,1887],[3077,1887],[3093,1881],[3103,1894],[3102,1874],[3093,1869],[3105,1870],[3111,1858],[3110,1895],[3124,1899],[3131,1881],[3144,1877],[3133,1886],[3146,1889],[3133,1891],[3168,1888],[3172,1866],[3183,1858],[3187,1826],[3176,1824],[3194,1797],[3178,1774],[3162,1766],[3156,1779],[3117,1761],[3119,1775],[3097,1784],[3092,1795],[3097,1783],[3096,1772],[3082,1774],[3110,1736],[3127,1740],[3138,1756],[3159,1740],[3187,1737],[3203,1725],[3210,1699],[3190,1698],[3192,1690],[3205,1682],[3235,1684],[3241,1675],[3262,1675],[3272,1637],[3286,1633],[3260,1692],[3238,1703],[3239,1732],[3231,1767],[3217,1783],[3258,1823],[3270,1815],[3249,1859],[3209,1900],[3211,1916],[3183,1980],[3196,1975],[3194,1987],[3203,1997],[3195,1995],[3175,2017],[3194,2030],[3207,2029],[3194,2046],[3179,2049],[3186,2075],[3215,2074],[3232,2105],[3250,2117],[3273,2089],[3330,2061],[3341,2049],[3370,2001],[3344,1990],[3321,2016],[3321,1997],[3311,1995],[3307,2006],[3305,1984],[3291,1993],[3294,1972],[3287,1985],[3266,1991],[3272,1999],[3262,1999],[3268,2009],[3258,2004],[3247,2014],[3239,1990],[3232,2003],[3235,1987],[3248,1976],[3232,1931],[3249,1880],[3283,1873],[3280,1883],[3254,1882],[3246,1919],[3237,1925],[3256,1964],[3266,1955],[3266,1968],[3288,1957],[3277,1953],[3281,1942],[3293,1948],[3316,1916],[3298,1954],[3313,1970],[3339,1952],[3324,1969],[3332,1984],[3347,1968],[3364,1980],[3375,1976],[3387,1964],[3378,1953],[3389,1962],[3399,1946],[3408,1946],[3396,1937],[3412,1943],[3429,1933],[3390,1971],[3390,2008],[3402,1974],[3451,1903],[3477,1909],[3508,1895],[3556,1852],[3573,1824],[3616,1797],[3610,1781],[3599,1780],[3601,1795],[3581,1797],[3584,1806],[3575,1800],[3573,1783],[3573,1772],[3579,1792],[3577,1762],[3585,1760],[3584,1783],[3601,1792],[3595,1778],[3608,1779],[3609,1771],[3602,1756],[3619,1769],[3630,1746],[3609,1734],[3622,1726],[3633,1673],[3625,1656],[3616,1662],[3603,1637],[3627,1651],[3604,1630],[3588,1604],[3564,1640],[3570,1625],[3553,1620],[3541,1601],[3527,1597],[3525,1569],[3523,1539],[3534,1502],[3533,1531],[3544,1544],[3542,1553],[3556,1554],[3546,1571],[3558,1578],[3555,1596],[3587,1546],[3603,1473],[3627,1443],[3625,1422],[3667,1400],[3667,1370],[3651,1351],[3682,1339],[3722,1374],[3778,1376],[3760,1362],[3748,1337],[3784,1353],[3807,1317],[3809,1292],[3822,1285],[3817,1297],[3825,1325],[3807,1354],[3832,1359],[3824,1361],[3827,1369],[3864,1376],[3877,1401],[3897,1405],[3907,1393],[3894,1372],[3903,1353],[3897,1343],[3906,1344],[3916,1320],[3943,1312],[3974,1284],[3993,1285],[4015,1251],[4016,1224],[4038,1198],[4057,1198],[4055,1187],[4073,1191],[4062,1199],[4074,1200],[4069,1208],[4070,1220],[4065,1247],[4057,1255],[4067,1262],[4057,1256],[4042,1296],[4022,1317],[4034,1330],[4024,1334],[4005,1320],[4005,1344],[4009,1369],[4025,1379],[4012,1378],[4004,1394],[4028,1418],[4017,1429],[3987,1431],[3971,1442],[3972,1476],[3957,1504],[3952,1553],[3942,1580],[3928,1593],[3932,1638],[3923,1673],[3881,1719],[3880,1735],[3894,1743],[3926,1726],[3923,1713],[3952,1698],[3956,1664],[3976,1664],[3979,1651],[4000,1650],[4003,1622],[4022,1623],[4023,1611],[4040,1604],[4036,1592],[4062,1588],[4062,1573],[4087,1555],[4095,1555],[4111,1553],[4115,1537],[4127,1533],[4121,1502],[4104,1505],[4096,1492],[4112,1499],[4112,1478],[4140,1496],[4160,1481],[4200,1507],[4224,1474],[4224,1532],[4190,1541],[4159,1541],[4133,1596],[4137,1606],[4178,1607],[4218,1604],[4224,1600],[4224,1660],[4208,1675],[4211,1663],[4203,1664],[4222,1658],[4194,1643],[4175,1662],[4175,1679],[4156,1678],[4161,1687],[4140,1688],[4138,1680],[4148,1682],[4128,1651],[4097,1650],[4070,1649],[4043,1687],[4056,1707],[4095,1718],[4082,1720],[4076,1739],[4078,1727],[4057,1724],[4052,1713],[4030,1710],[4030,1698],[4011,1694],[3982,1748],[3976,1783],[3959,1802],[3925,1812],[3906,1845],[3899,1878],[3908,1864],[3920,1880],[3920,1871],[3945,1880],[3949,1887],[3935,1887],[3939,1900],[3911,1900],[3906,1910],[3908,1885],[3893,1900],[3894,1887],[3884,1881],[3807,1927],[3795,1949],[3802,1978],[3593,2033],[3585,2049],[3571,2080],[3524,2110],[3517,2123],[3516,2140],[3532,2163],[3529,2177],[3536,2167],[3561,2172],[3575,2164],[3577,2174],[3549,2180],[3565,2191],[3571,2211],[3624,2208],[3642,2181],[3633,2209],[3658,2215],[3666,2233],[3650,2240],[3649,2226],[3620,2230],[3610,2225],[3611,2215],[3582,2225],[3572,2218],[3556,2222],[3544,2213],[3550,2197],[3538,2180],[3515,2183],[3492,2211],[3514,2208],[3529,2215],[3538,2235],[3573,2263],[3551,2256],[3551,2247],[3508,2218],[3497,2225],[3499,2240],[3489,2242],[3495,2251],[3478,2222],[3482,2204],[3496,2201],[3492,2177],[3473,2183],[3469,2173],[3449,2171],[3416,2188],[3408,2213],[3373,2236],[3372,2260],[3392,2266],[3397,2277],[3395,2310],[3412,2312],[3424,2326],[3422,2345],[3461,2323],[3458,2334],[3435,2347],[3420,2377],[3423,2387],[3439,2383],[3453,2390],[3454,2406],[3446,2397],[3429,2391],[3416,2421],[3429,2428],[3404,2425],[3421,2404],[3412,2398],[3409,2362],[3424,2364],[3386,2337],[3358,2377],[3330,2383],[3327,2413],[3317,2430],[3319,2451],[3328,2475],[3341,2479],[3353,2469],[3345,2477],[3350,2495],[3358,2493],[3369,2510],[3390,2502],[3389,2510],[3411,2510],[3370,2515],[3382,2540],[3391,2541],[3380,2550],[3356,2506],[3334,2492],[3318,2495],[3324,2515],[3318,2503],[3310,2498],[3315,2488],[3299,2467],[3305,2435],[3296,2430],[3299,2420],[3289,2427],[3269,2463],[3277,2460],[3282,2481],[3268,2466],[3259,2491],[3248,2537],[3260,2547],[3251,2543],[3247,2555],[3245,2543],[3231,2579],[3214,2595],[3197,2630],[3206,2627],[3203,2639],[3177,2701],[3135,2759],[3116,2805],[3104,2876],[3111,2884],[3138,2885],[3148,2820],[3144,2798],[3154,2834],[3141,2892],[3154,2875],[3169,2870],[3157,2851],[3165,2826],[3177,2824],[3170,2813],[3178,2799],[3202,2789],[3213,2794],[3189,2797],[3178,2816],[3193,2826],[3175,2830],[3171,2848],[3186,2880],[3193,2859],[3205,2853],[3193,2869],[3203,2878],[3201,2904],[3188,2906],[3175,2883],[3165,2900],[3154,2884],[3150,2905],[3183,2933],[3193,2924],[3216,2933],[3202,2943],[3200,2962],[3207,2972],[3205,2988],[3223,3007],[3194,2987],[3195,2998],[3229,3061],[3243,3129],[3240,3182],[3258,3195],[3250,3204],[3241,3199],[3247,3212],[3215,3281],[3073,3283],[3071,3283],[3032,3283],[3004,3303],[2976,3371],[2979,3405],[2970,3445],[2943,3481],[2943,3494],[2922,3493],[2951,3507],[2939,3508],[2932,3528],[2947,3520],[2931,3530],[2940,3549],[2920,3528],[2880,3594],[2860,3665],[2858,3698],[2867,3707],[2847,3750],[2857,3750],[2848,3751],[2853,3863],[2876,3855],[2854,3866],[2849,3917],[2820,3998],[2821,4035],[2842,4044],[2856,3991],[2890,3967],[2918,3973],[2908,3941],[2912,3906],[2919,3946],[2924,3926],[2930,3937],[2923,3962],[2932,3957],[2923,3972],[2951,3940],[2928,3836],[2933,3820],[2922,3857],[2923,3835],[2907,3828],[2904,3812],[2922,3826],[2936,3790],[2926,3778],[2918,3784],[2914,3758],[2900,3761],[2915,3749],[2907,3715],[2914,3700],[2922,3762],[2935,3749],[2929,3727],[2956,3736],[2955,3712],[2969,3763],[2988,3763],[2992,3722],[2979,3716],[2979,3701],[2998,3681],[2975,3653],[2959,3649],[2946,3662],[2958,3641],[2953,3631],[2933,3642],[2929,3631],[2939,3625],[2934,3609],[2945,3617],[2918,3606],[2932,3599],[2923,3593],[2938,3593],[2941,3601],[2952,3594],[2955,3613],[2963,3616],[2954,3620],[2969,3621],[2980,3627],[2979,3638],[2985,3630],[3000,3642],[3000,3622],[2983,3621],[2994,3612],[2975,3584],[2985,3592],[2984,3572],[2995,3591],[3002,3551],[2993,3527],[3007,3553],[3006,3601],[3016,3595],[3040,3577],[3017,3529],[3032,3527],[3036,3554],[3058,3554],[3047,3564],[3045,3587],[3036,3598],[3019,3614],[3026,3645],[3036,3653],[3034,3663],[3025,3658],[3027,3687],[3019,3682],[3007,3691],[3014,3715],[3033,3724],[3043,3800],[3059,3796],[3041,3737],[3057,3689],[3051,3680],[3059,3680],[3067,3675],[3061,3654],[3073,3642],[3073,3663],[3077,3637],[3073,3628],[3065,3625],[3064,3605],[3073,3622],[3081,3621],[3085,3612],[3090,3571],[3093,3607],[3075,3651],[3079,3671],[3102,3651],[3086,3674],[3097,3669],[3123,3640],[3124,3651],[3138,3647],[3125,3661],[3152,3732],[3161,3721],[3169,3736],[3171,3723],[3188,3727],[3186,3706],[3159,3700],[3148,3665],[3161,3677],[3165,3664],[3176,3660],[3173,3649],[3181,3644],[3170,3634],[3181,3632],[3181,3622],[3172,3625],[3176,3598],[3161,3609],[3148,3604],[3144,3623],[3132,3611],[3109,3614],[3120,3605],[3113,3574],[3121,3580],[3125,3606],[3141,3601],[3139,3592],[3158,3598],[3153,3573],[3143,3572],[3139,3563],[3158,3566],[3161,3576],[3175,3567],[3183,3546],[3194,3557],[3190,3545],[3179,3542],[3190,3543],[3191,3533],[3177,3532],[3191,3531],[3191,3513],[3204,3506],[3211,3538],[3206,3526],[3197,3546],[3205,3561],[3217,3558],[3224,3568],[3212,3573],[3222,3576],[3230,3566],[3250,3562],[3251,3576],[3260,3569],[3265,3578],[3264,3589],[3255,3590],[3259,3600],[3270,3601],[3274,3592],[3293,3596],[3278,3596],[3269,3609],[3273,3620],[3261,3620],[3264,3611],[3248,3614],[3230,3590],[3230,3648],[3253,3651],[3258,3631],[3268,3627],[3277,3626],[3294,3644],[3302,3633],[3308,3658],[3296,3662],[3295,3683],[3318,3690],[3318,3675],[3318,3685],[3331,3685],[3318,3691],[3326,3713],[3318,3749],[3322,3774],[3320,3830],[3332,3821],[3331,3794],[3341,3772],[3340,3814],[3348,3806],[3367,3807],[3374,3794],[3368,3767],[3378,3753],[3370,3729],[3382,3741],[3388,3718],[3385,3692],[3392,3701],[3394,3688],[3396,3736],[3378,3764],[3377,3804],[3370,3816],[3341,3823],[3313,3975],[3340,4009],[3347,4053],[3375,4064],[3358,4069],[3352,4090],[3363,4085],[3363,4095],[3363,4097],[3351,4097],[3336,4132],[3339,4140],[3347,4136],[3338,4143],[3333,4172],[3343,4187],[3350,4178],[3342,4153],[3358,4157],[3364,4144],[3376,4143],[3370,4133],[3382,4134],[3382,4126],[3397,4133],[3412,4121],[3411,4107],[3426,4095],[3447,4079],[3434,4095],[3422,4108],[3430,4116],[3415,4123],[3432,4132],[3381,4147],[3388,4166],[3375,4160],[3354,4196],[3357,4209],[3374,4204],[3370,4224],[3394,4224],[3407,4205],[3415,4210],[3423,4197],[3440,4196],[3436,4184],[3446,4195],[3462,4189],[3471,4195],[3431,4202],[3426,4213],[3407,4224],[3492,4224],[3492,4214],[3504,4219],[3519,4197],[3519,4205],[3534,4208],[3540,4194],[3554,4190],[3555,4177],[3543,4181],[3542,4146],[3532,4145],[3547,4138],[3541,4097],[3542,4085],[3529,4075],[3539,4068],[3538,4079],[3546,4082],[3571,4062],[3595,4025],[3604,4025],[3622,3995],[3611,4014],[3613,4022],[3593,4031],[3578,4058],[3585,4067],[3577,4064],[3550,4085],[3555,4097],[3563,4098],[3556,4120],[3574,4111],[3556,4126],[3558,4139],[3550,4148],[3563,4173],[3586,4157],[3586,4140],[3593,4151],[3603,4135],[3609,4145],[3635,4134],[3588,4160],[3565,4189],[3570,4199],[3645,4193],[3605,4203],[3608,4214],[3591,4201],[3586,4215],[3573,4206],[3563,4209],[3563,4201],[3553,4204],[3540,4221],[3546,4224],[3275,4224],[3266,4212],[3279,4218],[3289,4199],[3274,4194],[3279,4180],[3261,4189],[3271,4177],[3266,4168],[3263,4158],[3287,4177],[3299,4162],[3252,4108],[3248,4128],[3238,4106],[3246,4101],[3220,4105],[3228,4123],[3206,4134],[3212,4120],[3194,4119],[3201,4110],[3191,4095],[3179,4089],[3186,4069],[3171,4059],[3165,4072],[3161,4085],[3159,4075],[3149,4081],[3145,4068],[3157,4065],[3148,4061],[3167,4049],[3164,4029],[3156,4017],[3151,4027],[3152,4035],[3137,4038],[3137,4057],[3132,4040],[3124,4037],[3136,4030],[3128,4014],[3140,4016],[3140,3987],[3180,3967],[3175,3949],[3100,4026],[3096,4037],[3108,4063],[3091,4065],[3079,4085],[3071,4081],[3056,4084],[3047,4074],[3033,4097],[3018,4123],[3013,4192],[2988,4224],[3027,4224],[3044,4223],[3040,4206],[3046,4219],[3051,4224],[3074,4224],[3074,4216],[3076,4224],[3116,4224],[3111,4198],[3098,4192],[3094,4178],[3075,4180],[3069,4127],[3080,4145],[3084,4173],[3089,4165],[3100,4169],[3124,4202],[3132,4190],[3125,4181],[3134,4185],[3139,4173],[3127,4143],[3138,4148],[3157,4136],[3154,4122],[3144,4124],[3155,4117],[3153,4109],[3166,4134],[3140,4155],[3146,4172],[3131,4214],[3133,4224],[3161,4224],[3164,4180],[3176,4203],[3203,4177],[3199,4162],[3213,4155],[3207,4166],[3216,4186],[3208,4187],[3205,4199],[3189,4197],[3188,4215],[3170,4221],[3169,4224],[4224,4224],[4224,4224],[4224,-128],[4224,-128],[4224,4224],[2293,4224]], - [[2681,3125],[2665,3123],[2657,3113],[2655,3124],[2640,3119],[2663,3099],[2642,3105],[2640,3089],[2618,3108],[2622,3138],[2622,3153],[2653,3192],[2652,3210],[2685,3144],[2681,3125],[2681,3125]], - [[3189,3788],[3205,3783],[3206,3763],[3193,3756],[3189,3788],[3189,3788]], - [[2264,3287],[2274,3283],[2269,3270],[2264,3287],[2264,3287]], - [[2436,3801],[2448,3809],[2446,3798],[2462,3796],[2473,3772],[2449,3781],[2436,3801],[2436,3801]], - [[3142,2365],[3155,2362],[3162,2350],[3157,2333],[3137,2341],[3122,2401],[3142,2382],[3142,2365],[3142,2365]], - [[2761,2561],[2769,2563],[2780,2549],[2761,2561],[2761,2561]], - [[2923,2209],[2910,2200],[2893,2208],[2898,2222],[2888,2211],[2896,2176],[2880,2194],[2862,2195],[2864,2218],[2876,2232],[2865,2227],[2886,2247],[2879,2258],[2884,2266],[2892,2260],[2894,2239],[2912,2246],[2917,2236],[2916,2251],[2907,2248],[2924,2290],[2934,2286],[2922,2272],[2928,2254],[2955,2248],[2946,2241],[2942,2214],[2923,2209],[2923,2209]], - [[2823,2539],[2896,2498],[2911,2465],[2876,2449],[2805,2496],[2788,2496],[2792,2523],[2823,2539],[2823,2539]], - [[3675,1790],[3740,1742],[3708,1651],[3683,1646],[3674,1634],[3638,1646],[3652,1647],[3661,1664],[3670,1660],[3649,1717],[3641,1722],[3647,1736],[3635,1756],[3653,1759],[3655,1741],[3666,1743],[3674,1731],[3662,1730],[3661,1711],[3670,1711],[3674,1691],[3678,1695],[3678,1649],[3688,1650],[3692,1665],[3684,1671],[3686,1698],[3696,1689],[3696,1708],[3707,1709],[3696,1719],[3707,1731],[3719,1729],[3702,1729],[3696,1741],[3688,1759],[3676,1769],[3675,1790],[3675,1790]] -]; - -const canvas = document.getElementById('canvas'); -const ctx = canvas.getContext('2d'); - -let minX = Infinity, - maxX = -Infinity, - minY = Infinity, - maxY = -Infinity; - -for (let i = 0; i < testPoints[0].length; i++) { - minX = Math.min(minX, testPoints[0][i][0]); - maxX = Math.max(maxX, testPoints[0][i][0]); - minY = Math.min(minY, testPoints[0][i][1]); - maxY = Math.max(maxY, testPoints[0][i][1]); -} - -const width = maxX - minX; -const height = maxY - minY; - -canvas.width = window.innerWidth; -canvas.height = canvas.width * height / width + 10; - -const ratio = (canvas.width - 10) / width; - -if (devicePixelRatio > 1) { - canvas.style.width = `${canvas.width}px`; - canvas.style.height = `${canvas.height}px`; - canvas.width *= 2; - canvas.height *= 2; - ctx.scale(2, 2); -} - -const data = flatten(testPoints); - -console.time('earcut'); -const result = earcut(data.vertices, data.holes, data.dimensions); -console.timeEnd('earcut'); - -console.log(`deviation: ${deviation(data.vertices, data.holes, data.dimensions, result)}`); - -const triangles = []; -for (const index of result) { - triangles.push([data.vertices[index * data.dimensions], data.vertices[index * data.dimensions + 1]]); -} - -ctx.lineJoin = 'round'; - -for (let i = 0; i < triangles.length; i += 3) { - drawPoly(triangles.slice(i, i + 3), 'rgba(255,0,0,0.2)', 'rgba(255,255,0,0.2)'); - // drawPoly(triangles.slice(i, i + 3), 'rgba(255,0,0,0.0)', 'rgba(255,0,0,0.3)'); -} - -drawPoly(testPoints, 'black', true); - -function drawPoint(p, color) { - const x = (p[0] - minX) * ratio + 5, - y = (p[1] - minY) * ratio + 5; - ctx.fillStyle = color || 'grey'; - ctx.fillRect(x - 3, y - 3, 6, 6); -} - -function drawPoly(rings, color, fill) { - ctx.beginPath(); - - ctx.strokeStyle = color; - if (fill && fill !== true) ctx.fillStyle = fill; - - if (typeof rings[0][0] === 'number') rings = [rings]; - - for (const points of rings) { - for (let i = 0; i < points.length; i++) { - const x = (points[i][0] - minX) * ratio + 5, - y = (points[i][1] - minY) * ratio + 5; - if (i === 0) ctx.moveTo(x, y); - else ctx.lineTo(x, y); +(async function () { + const params = new URLSearchParams(window.location.search.substring(1)); + const fixture = params.get('fixture') || 'water'; + const testPoints = await (await fetch(`../test/fixtures/${fixture}.json`)).json(); + const rotation = params.get('rotation') || 0; + const theta = rotation * Math.PI / 180; + const round = rotation % 90 === 0 ? Math.round : x => x; + const xx = round(Math.cos(theta)); + const xy = round(-Math.sin(theta)); + const yx = round(Math.sin(theta)); + const yy = round(Math.cos(theta)); + for (const ring of testPoints) { + for (const coord of ring) { + const [x, y] = coord; + coord[0] = xx * x + xy * y; + coord[1] = yx * x + yy * y; } - if (fill) ctx.closePath(); } - ctx.stroke(); - - if (fill && fill !== true) ctx.fill('evenodd'); -} - -function clear() { - ctx.clearRect(0, 0, canvas.width, canvas.height); -} - -function drawNode(node, color) { - drawPoint([node.x, node.y], color); -} - -function drawNodeRing(node, color, fill) { - const start = node; - const points = []; - do { - points.push([node.x, node.y]); - node = node.next; - } while (node !== start); - - console.log(JSON.stringify(points)); - drawPoly(points, color, fill); -} - -function drawNodePolygon(node) { - drawNodeRing(node, 'black', 'rgba(255,255,0,0.2)'); -} - -function drawNodeEdge(node, color) { - drawPoly([[node.x, node.y], [node.next.x, node.next.y]], color); -} + + const canvas = document.getElementById('canvas'); + const ctx = canvas.getContext('2d'); + + let minX = Infinity, + maxX = -Infinity, + minY = Infinity, + maxY = -Infinity; + + for (let i = 0; i < testPoints[0].length; i++) { + minX = Math.min(minX, testPoints[0][i][0]); + maxX = Math.max(maxX, testPoints[0][i][0]); + minY = Math.min(minY, testPoints[0][i][1]); + maxY = Math.max(maxY, testPoints[0][i][1]); + } + + const width = maxX - minX; + const height = maxY - minY; + + canvas.width = window.innerWidth; + canvas.height = canvas.width * height / width + 10; + + const ratio = (canvas.width - 10) / width; + + if (devicePixelRatio > 1) { + canvas.style.width = `${canvas.width}px`; + canvas.style.height = `${canvas.height}px`; + canvas.width *= 2; + canvas.height *= 2; + ctx.scale(2, 2); + } + + const data = flatten(testPoints); + + console.time('earcut'); + const result = earcut(data.vertices, data.holes, data.dimensions); + console.timeEnd('earcut'); + + console.log(`deviation: ${deviation(data.vertices, data.holes, data.dimensions, result)}`); + + const triangles = []; + for (const index of result) { + triangles.push([data.vertices[index * data.dimensions], data.vertices[index * data.dimensions + 1]]); + } + + ctx.lineJoin = 'round'; + + for (let i = 0; i < triangles.length; i += 3) { + drawPoly(triangles.slice(i, i + 3), 'rgba(255,0,0,0.2)', 'rgba(255,255,0,0.2)'); + // drawPoly(triangles.slice(i, i + 3), 'rgba(255,0,0,0.0)', 'rgba(255,0,0,0.3)'); + } + + drawPoly(testPoints, 'black', true); + + function drawPoint(p, color) { + const x = (p[0] - minX) * ratio + 5, + y = (p[1] - minY) * ratio + 5; + ctx.fillStyle = color || 'grey'; + ctx.fillRect(x - 3, y - 3, 6, 6); + } + + function drawPoly(rings, color, fill) { + ctx.beginPath(); + + ctx.strokeStyle = color; + if (fill && fill !== true) ctx.fillStyle = fill; + + if (typeof rings[0][0] === 'number') rings = [rings]; + + for (const points of rings) { + for (let i = 0; i < points.length; i++) { + const x = (points[i][0] - minX) * ratio + 5, + y = (points[i][1] - minY) * ratio + 5; + if (i === 0) ctx.moveTo(x, y); + else ctx.lineTo(x, y); + } + if (fill) ctx.closePath(); + } + ctx.stroke(); + + if (fill && fill !== true) ctx.fill('evenodd'); + } + + function clear() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + } + + function drawNode(node, color) { + drawPoint([node.x, node.y], color); + } + + function drawNodeRing(node, color, fill) { + const start = node; + const points = []; + do { + points.push([node.x, node.y]); + node = node.next; + } while (node !== start); + + console.log(JSON.stringify(points)); + drawPoly(points, color, fill); + } + + function drawNodePolygon(node) { + drawNodeRing(node, 'black', 'rgba(255,255,0,0.2)'); + } + + function drawNodeEdge(node, color) { + drawPoly([[node.x, node.y], [node.next.x, node.next.y]], color); + } +})();