| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 | "use strict";// Cohen-Sutherland line clipping algorithm, adapted to efficiently// handle polylines rather than just segmentsObject.defineProperty(exports, "__esModule", { value: true });function lineclip(points, bbox, result) {    var len = points.length, codeA = bitCode(points[0], bbox), part = [], i, codeB, lastCode;    var a;    var b;    if (!result)        result = [];    for (i = 1; i < len; i++) {        a = points[i - 1];        b = points[i];        codeB = lastCode = bitCode(b, bbox);        while (true) {            if (!(codeA | codeB)) {                // accept                part.push(a);                if (codeB !== lastCode) {                    // segment went outside                    part.push(b);                    if (i < len - 1) {                        // start a new line                        result.push(part);                        part = [];                    }                }                else if (i === len - 1) {                    part.push(b);                }                break;            }            else if (codeA & codeB) {                // trivial reject                break;            }            else if (codeA) {                // a outside, intersect with clip edge                a = intersect(a, b, codeA, bbox);                codeA = bitCode(a, bbox);            }            else {                // b outside                b = intersect(a, b, codeB, bbox);                codeB = bitCode(b, bbox);            }        }        codeA = lastCode;    }    if (part.length)        result.push(part);    return result;}exports.lineclip = lineclip;// Sutherland-Hodgeman polygon clipping algorithmfunction polygonclip(points, bbox) {    var result, edge, prev, prevInside, i, p, inside;    // clip against each side of the clip rectangle    for (edge = 1; edge <= 8; edge *= 2) {        result = [];        prev = points[points.length - 1];        prevInside = !(bitCode(prev, bbox) & edge);        for (i = 0; i < points.length; i++) {            p = points[i];            inside = !(bitCode(p, bbox) & edge);            // if segment goes through the clip window, add an intersection            if (inside !== prevInside)                result.push(intersect(prev, p, edge, bbox));            if (inside)                result.push(p); // add a point if it's inside            prev = p;            prevInside = inside;        }        points = result;        if (!points.length)            break;    }    return result;}exports.polygonclip = polygonclip;// intersect a segment against one of the 4 lines that make up the bboxfunction intersect(a, b, edge, bbox) {    return edge & 8        ? [a[0] + ((b[0] - a[0]) * (bbox[3] - a[1])) / (b[1] - a[1]), bbox[3]] // top        : edge & 4            ? [a[0] + ((b[0] - a[0]) * (bbox[1] - a[1])) / (b[1] - a[1]), bbox[1]] // bottom            : edge & 2                ? [bbox[2], a[1] + ((b[1] - a[1]) * (bbox[2] - a[0])) / (b[0] - a[0])] // right                : edge & 1                    ? [bbox[0], a[1] + ((b[1] - a[1]) * (bbox[0] - a[0])) / (b[0] - a[0])] // left                    : null;}// bit code reflects the point position relative to the bbox://         left  mid  right//    top  1001  1000  1010//    mid  0001  0000  0010// bottom  0101  0100  0110function bitCode(p, bbox) {    var code = 0;    if (p[0] < bbox[0])        code |= 1;    // left    else if (p[0] > bbox[2])        code |= 2; // right    if (p[1] < bbox[1])        code |= 4;    // bottom    else if (p[1] > bbox[3])        code |= 8; // top    return code;}
 |