supportCalculations.js 1.96 KB
// Taken from three-mesh-bvh's selection.js example
const pointRayCrossesLine = (point, line, prevDirection, thisDirection) => {
    const { start, end } = line;
    const px = point.x;
    const py = point.y;
    const sy = start.y;
    const ey = end.y;
    if (sy === ey) return false;
    if (py > sy && py > ey) return false; // above
    if (py < sy && py < ey) return false; // below
    const sx = start.x;
    const ex = end.x;
    if (px > sx && px > ex) return false; // right
    if (px < sx && px < ex) {
        // left
        if (py === sy && prevDirection !== thisDirection) {
            return false;
        }
        return true;
    }
    // check the side
    const dx = ex - sx;
    const dy = ey - sy;
    const perpx = dy;
    const perpy = -dx;
    const pdx = px - sx;
    const pdy = py - sy;
    const dot = perpx * pdx + perpy * pdy;
    if (Math.sign(dot) !== Math.sign(perpx)) {
        return true;
    }
    return false;
};

// Taken from three-mesh-bvh's selection.js example
export const pointRayCrossesSegments = (point, segments) => {
    let crossings = 0;
    const firstSeg = segments[segments.length - 1];
    let prevDirection = firstSeg.start.y > firstSeg.end.y;
    for (let s = 0, l = segments.length; s < l; s++) {
        const line = segments[s];
        const thisDirection = line.start.y > line.end.y;
        if (pointRayCrossesLine(point, line, prevDirection, thisDirection)) {
            crossings++;
        }
        prevDirection = thisDirection;
    }
    return crossings;
};

// Taken from three-mesh-bvh's selection.js example
// https://stackoverflow.com/questions/3838329/how-can-i-check-if-two-segments-intersect
export const lineCrossesLine = (l1, l2) => {
    function ccw(A, B, C) {
        return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x);
    }

    const A = l1.start;
    const B = l1.end;

    const C = l2.start;
    const D = l2.end;

    return ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D);
};