I found this function on Stackoverflow some time ago and only now am I realizing that it sometimes seems to give false-positives. Here it is:
function lineIntersectsCircle(p1X, p1Y, p2X, p2Y, cX, cY, r) {
let xDelta = p1X - p2X;
let yDelta = p1Y - p2Y;
let distance = Math.sqrt(xDelta * xDelta + yDelta * yDelta)
let a = (cY - p1Y) * (p2X - p1X);
let b = (cX - p1X) * (p2Y - p1Y);
return Math.abs(a - b) / distance <= r;
}
Here's a full code demo reproduction showing the issue here:
let ctx = document.querySelector("canvas").getContext("2d");
function drawCircle(xCenter, yCenter, radius) {
ctx.beginPath();
ctx.arc(xCenter, yCenter, radius, 0, 2 * Math.PI);
ctx.fill();
}
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
function lineIntersectsCircle(p1X, p1Y, p2X, p2Y, cX, cY, r) {
let xDelta = p1X - p2X;
let yDelta = p1Y - p2Y;
let distance = Math.sqrt(xDelta * xDelta + yDelta * yDelta)
let a = (cY - p1Y) * (p2X - p1X);
let b = (cX - p1X) * (p2Y - p1Y);
return Math.abs(a - b) / distance <= r;
}
let circleX = 250;
let circleY = 250;
let circleR = 50;
let lineX1 = 50;
let lineY1 = 350;
let lineX2 = 185;
let lineY2 = 250;
draw = () => {
ctx.fillStyle = "#b2c7ef";
ctx.fillRect(0, 0, 800, 800);
ctx.fillStyle = "#ffffff";
drawCircle(circleX, circleY, circleR);
drawLine(lineX1, lineY1, lineX2, lineY2);
}
console.log(lineIntersectsCircle(lineX1, lineY1, lineX2, lineY2, circleX, circleY, circleR))
draw();
canvas { display: flex; margin: 0 auto; }
<canvas width="400" height="400"></canvas>
As you can see, the line doesn't intersect the circle, yet it console logs a true statement. Does anyone know why this would be? If this function is incorrect, what is the proper function for only determining if a line and circle intersect? I do not need the intersection points, only whether or not they intersect at all.