function triangulate(poly, context) {
const pl = poly.length;
const triangles = [];
const polyC = poly.slice();
if (pl <= 3) return poly;
const [left, index] = polyC.reduce(
(acc, cur, i) => {
const [old, ind] = acc;
if (old.length === 0) return [cur, i];
if (cur[0] < old[0]) return [cur, i];
if (cur[0] === old[0]) {
if (cur[1] < old[1]) return [cur, i];
}
return acc;
},
[[], -1]
);
let trian = [
polyC[index > 0 ? index - 1 : pl - 1],
polyC[index],
polyC[(index + 1) % pl]
];
const ccw = orientation(trian);
while (polyC.length >= 3) {
let reflex = [];
let eartip = -1;
for (let i = 0; i < polyC.length; ++i) {
if (eartip >= 0) break;
const p = i > 0 ? i - 1 : polyC.length - 1;
const n = (i + 1) % polyC.length;
const tri = [polyC[p], polyC[i], polyC[n]];
if (orientation(tri) !== ccw) {
reflex.push(i);
}
let isEar = true;
for (let j = 0; j < reflex.length; ++j) {
if (reflex[j] === p || reflex[j] === n) continue;
if (inTriangle(tri, polyC[reflex[j]])) {
isEar = false;
break;
}
}
if (isEar) {
for (let j = i + 1; j < polyC.length; ++j) {
if (j === p || j === n) continue;
if (inTriangle(tri, polyC[j])) {
isEar = false;
break;
}
}
}
if (isEar) eartip = i;
}
if (eartip < 0) break;
const earp = eartip > 0 ? eartip - 1 : polyC.length - 1;
const earn = (eartip + 1) % polyC.length;
const parts = [polyC[earp], polyC[eartip], polyC[earn]];
triangles.push(parts);
polyC.splice(eartip, 1);
}
return triangles;
}