Ray Tracing

It would be nice to have a ray tracing component or hittest method. Posting Joseph's code here for reference.

const Intersection = {
    ofLines: function (ptA, ptB, ptC, ptD, lineSegmentOnly) {
        if ((ptA.x === ptB.x && ptA.y === ptB.y) || (ptC.x === ptD.x && ptC.y === ptD.y)) {
            return null;
        }

        const denominator = ((ptD.y - ptC.y) * (ptB.x - ptA.x) - (ptD.x - ptC.x) * (ptB.y - ptA.y));

        // Lines are parallel
        if (denominator === 0) {
            return null;
        }

        const ua = ((ptD.x - ptC.x) * (ptA.y - ptC.y) - (ptD.y - ptC.y) * (ptA.x - ptC.x)) / denominator;

        // Check if the intersection point is within the bounds of the line segments if required
        if (lineSegmentOnly) {
            const ub = ((ptB.x - ptA.x) * (ptA.y - ptC.y) - (ptB.y - ptA.y) * (ptA.x - ptC.x)) / denominator;
            if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
                return null;
            }
        }

        // Return an object with the x and y coordinates of the intersection
        const x = ptA.x + ua * (ptB.x - ptA.x);
        const y = ptA.y + ua * (ptB.y - ptA.y);

        return {x, y};
    },

    ofRectAndExitingRay: function (ptA, ptB, rect) {
        const lineLen = Math.sqrt((ptB.x - ptA.x) ** 2 + (ptB.y - ptA.y) ** 2);
        // 1.42 ensures the minimum value necessary to reach outside the rect (just exceeds hypotenuse)
        const rayLen = Math.max(rect.width, rect.height) * 1.42;
        const extendX = (ptB.x - ptA.x) / lineLen * rayLen;
        const extendY = (ptB.y - ptA.y) / lineLen * rayLen;
        const farPt = {x: ptA.x + extendX, y: ptA.y + extendY};

        // Define the bounding box to test
        const rectCornerPts = [
            {x: 0, y: 0},
            {x: rect.width, y: 0},
            {x: rect.width, y: rect.height},
            {x: 0, y: rect.height}
        ];

        let intersectionPt = null;
        for (let i = 1; i <= rectCornerPts.length && intersectionPt == null; ++i) {
            const edgePtA = rectCornerPts[i - 1];
            const edgePtB = rectCornerPts[i % rectCornerPts.length];
            intersectionPt = this.ofLines(ptA, farPt, edgePtA, edgePtB, true);
        }
        return intersectionPt;
    }
}
1 Like

Sounds cool. Can you describe what it does or post an example?