Line intersection
geometryfunctionjavascriptarchivedLines crossing test
A simple function for testing if two lines on a 2D plane cross one another. If they do, the coordinates at which they meet or cross are returned, otherwise the function returns false.
function lineIntersection(l1, l2)
{
var s1 = [0,0], s2 = [0,0];
s1[0] = l1[1][0] - l1[0][0];
s1[1] = l1[1][1] - l1[0][1];
s2[0] = l2[1][0] - l2[0][0];
s2[1] = l2[1][1] - l2[0][1];
var s = (-s1[1] * (l1[0][0] - l2[0][0]) + s1[0] * (l1[0][1] - l2[0][1])) / (-s2[0] * s1[1] + s1[0] * s2[1]);
var t = ( s2[0] * (l1[0][1] - l2[0][1]) - s2[1] * (l1[0][0] - l2[0][0])) / (-s2[0] * s1[1] + s1[0] * s2[1]);
if(s >= 0 && s <= 1 && t >= 0 && t <= 1)
{
return [l1[0][0] + (t * s1[0]),
l1[0][1] + (t * s1[1])];
}
return false;
}
Example source code
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var ctx = null, game = null;
var line1 = {
point1 : [10,10],
point2 : [590,390],
whichPoint : 1
};
var line2 = {
point1 : [10,390],
point2 : [590,10],
whichPoint : 1
};
var intersection = false;
window.onload = function() {
game = document.getElementById('game');
ctx = game.getContext('2d');
ctx.font = "bold 10pt sans-serif";
intersection = lineIntersection(
[line1.point1, line1.point2],
[line2.point1, line2.point2]
);
document.addEventListener('contextmenu', event => event.preventDefault);
game.addEventListener('mouseup', function(e) {
e.preventDefault();
// Get the position of the mouse click on the page
mouseX = e.pageX;
mouseY = e.pageY;
// Find the offset of the Canvas relative to the document top, left,
// and modify the mouse position to account for this
var p = game;
do
{
mouseX-= p.offsetLeft;
mouseY-= p.offsetTop;
p = p.offsetParent;
} while(p!=null);
// Which line?
if(e.which==1)
{
if(line1.whichPoint == 1) { line1.point1 = [mouseX, mouseY]; }
else if(line1.whichPoint == 2) { line1.point2 = [mouseX, mouseY]; }
line1.whichPoint = (line1.whichPoint==1 ? 2 : 1);
}
else if(e.which==3)
{
if(line2.whichPoint == 1) { line2.point1 = [mouseX, mouseY]; }
else if(line2.whichPoint == 2) { line2.point2 = [mouseX, mouseY]; }
line2.whichPoint = (line2.whichPoint==1 ? 2 : 1);
}
intersection = lineIntersection(
[line1.point1, line1.point2],
[line2.point1, line2.point2]
);
});
requestAnimationFrame(drawGame);
};
function lineIntersection(l1, l2)
{
var s1 = [0,0], s2 = [0,0];
s1[0] = l1[1][0] - l1[0][0];
s1[1] = l1[1][1] - l1[0][1];
s2[0] = l2[1][0] - l2[0][0];
s2[1] = l2[1][1] - l2[0][1];
var s = (-s1[1] * (l1[0][0] - l2[0][0]) + s1[0] * (l1[0][1] - l2[0][1])) / (-s2[0] * s1[1] + s1[0] * s2[1]);
var t = ( s2[0] * (l1[0][1] - l2[0][1]) - s2[1] * (l1[0][0] - l2[0][0])) / (-s2[0] * s1[1] + s1[0] * s2[1]);
if(s >= 0 && s <= 1 && t >= 0 && t <= 1)
{
return [l1[0][0] + (t * s1[0]),
l1[0][1] + (t * s1[1])];
}
return false;
}
function drawGame()
{
if(ctx==null) { return; }
// Clear the Canvas
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 600, 400);
// Draw crossing point, if these lines intersect
if(intersection)
{
ctx.fillStyle = "#cccc00";
ctx.strokeStyle = "#000000";
ctx.beginPath();
ctx.arc(intersection[0], intersection[1], 10, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
// Draw line 1
ctx.strokeStyle = "#ff0000";
ctx.beginPath();
ctx.moveTo(line1.point1[0], line1.point1[1]);
ctx.lineTo(line1.point2[0], line1.point2[1]);
ctx.closePath();
ctx.stroke();
// Draw line 2
ctx.strokeStyle = "#0000ff";
ctx.beginPath();
ctx.moveTo(line2.point1[0], line2.point1[1]);
ctx.lineTo(line2.point2[0], line2.point2[1]);
ctx.closePath();
ctx.stroke();
// Show some information...
ctx.fillStyle = "#ff0000";
ctx.fillText("Line 1 from " + line1.point1[0] + "," + line1.point1[1] + " to " + line1.point2[0] + "," + line1.point2[1], 10, 20);
ctx.fillStyle = "#0000ff";
ctx.fillText("Line 2 from " + line2.point1[0] + "," + line2.point1[1] + " to " + line2.point2[0] + "," + line2.point2[1], 10, 40);
ctx.fillStyle = "#000000";
ctx.fillText("Intersection point: " + (intersection==false ? "none" : Math.round(intersection[0])+", "+Math.round(intersection[1])), 10, 60);
// Ask for the next animation frame
requestAnimationFrame(drawGame);
}
</script>
</head>
<body>
<p>Left click to place the start or end point of the red line. Right click to change the start or end point of the blue line. If the lines intersect, the crossing point will be highlighted.</p>
<canvas id="game" width="600" height="400"></canvas>
<ul id="pointList" style="font-family:monospace;"></ul>
</body>
</html>