Line to Line Intersection
// line to line intersection https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
function lineIntersection(p1, p2, p3, p4) {
let ip = { x: 0, y: 0 };
// rare case where I use `_` in a non-constant variable name
// to make this easy to read to with the wikipedia info
const x4_x3 = p4.x - p3.x;
const y4_y3 = p4.y - p3.y;
const x2_x1 = p2.x - p1.x;
const y2_y1 = p2.y - p1.y;
const x1_x3 = p1.x - p3.x;
const y1_y3 = p1.y - p3.y;
let nx, ny, dn;
nx = x4_x3 * y1_y3 - y4_y3 * x1_x3;
ny = x2_x1 * y1_y3 - y2_y1 * x1_x3;
dn = y4_y3 * x2_x1 - x4_x3 * y2_y1;
nx /= dn;
ny /= dn;
// has intersection
if (nx >= 0 && nx <= 1 && ny >= 0 && ny <= 1) {
ny = p1.y + nx * y2_y1;
nx = p1.x + nx * x2_x1;
ip.x = nx;
ip.y = ny;
} else {
// no intersection
ip = null;
}
return ip;
}
const el = document.body.appendChild(
document.createElement('div'));
// hard coding line values for simplicity and ease of understanding
el.innerHTML = `
<svg width="100%" height="100%" viewBox="0 0 550 496">
<path id='path' d="M 10 10 L 300 300 M 100 10 L 160 320" stroke="black" fill='none' vector-effect="non-scaling-stroke"/>
<rect id="intersecton" x="0" y="0" width="10" height="10" fill="red" />
</svg>
<style>
svg, div, body, html {
overflow: visible;
height: 100%;
width: 100%;
margin: 0; padding: 0;
}
</style>
`;
const loc = lineIntersection(
{x: 10, y: 10}, {x: 300, y:300},
{x: 100, y: 10}, {x: 160, y:320}
);
// subtract half the size of the rect from both axis to center it
intersecton.x.baseVal.value = loc.x - 5;
// @NOTE: using the `id` global `window.intersection`
// is just good for demos - little risky for real stuff
// since it lends itself to easy collision
window.intersecton.y.baseVal.value = loc.y - 5;
Line to line intersection rendered with SVG.