function clipInfinite(polygon) {
let P = polygon.points.slice(), p, n;
if (p = project(P[0], polygon.v0)) P.unshift(p);
if (p = project(P[P.length - 1], polygon.vn)) P.unshift(p);
if (n = (P = clip(P)).length) {
for (let i = 0, c0, c1 = sidecode(P[n - 1]); i < n; ++i) {
c0 = c1, c1 = sidecode(P[i]);
if (c0 && c1) {
while (c0 !== c1) {
let c;
switch (c0) {
case 0b0101: c0 = 0b0100; continue;
case 0b0100: c0 = 0b0110, c = [xmax, ymin]; break;
case 0b0110: c0 = 0b0010; continue;
case 0b0010: c0 = 0b1010, c = [xmax, ymax]; break;
case 0b1010: c0 = 0b1000; continue;
case 0b1000: c0 = 0b1001, c = [xmin, ymax]; break;
case 0b1001: c0 = 0b0001; continue;
case 0b0001: c0 = 0b0101, c = [xmin, ymin]; break;
}
if (contains(polygon, c)) {
P.splice(i, 0, c), ++n, ++i;
}
}
}
}
} else if (contains(polygon, [(xmin + xmax) / 2, (ymin + ymax) / 2])) {
P.push([xmin, ymin], [xmax, ymin], [xmax, ymax], [xmin, ymax]);
}
return P;
}