If I have a line, with the points x,y,endx and endy how can I detect if another point is on the line? A simple equation, or example functions in JavaScript or pseudocode will be most helpful.
EDIT: This is for a game I'm working on, I'm trying to detect if a laser is colliding with an object, Here is the sample http://jefnull.com/references/lasers/ The file that will be most descriptive is http://jefnull.com/references/lasers/lasers.js
Normalize the vectors. Check if the normals match. Find the greatest value, divide all of the other values by that value so you get a vector normal. Any point on a line should have the same vector normal.
The simplest is as follows. if (x-x1)/(x2-x1) = (y-y1)/(y2-y1) = alpha (a constant), then the point C(x,y) will lie on the line between pts 1 & 2.
Line Segment Formula Now, let us see how to find the length of a line segment when the coordinates of the two endpoints are given. In this case, we use the distance formula, that is, D = √[(x2−x1 x 2 − x 1 )2 + (y2−y1 y 2 − y 1 )2].
You want to check whether the slopes are the same between the pairs of points. But you should be careful not to ever divide by zero, so check by checking the cross-multiplied version of the equations.
More explicitly, if your points are A = (Ax, Ay)
, B = (Bx, By)
, C = (Cx, Cy)
, then you would like to check that
(Cy - Ay) / (Cx - Ax) = (By - Ay) / (Bx - Ax)
But instead you should check that
(Cy - Ay) * (Bx - Ax) = (By - Ay) * (Cx - Ax).
First of all, the answer provided by Razack was the most mathematically sound answer, though highly theoretical. If you are upvoting this answer, please consider upvoting his answer too.
I have implemented his methods in the following useful javascript functions. Have a look in particular at function calcIsInsideThickLineSegment(...). Use as you please.
//Returns {.x, .y}, a projected point perpendicular on the (infinite) line.
function calcNearestPointOnLine(line1, line2, pnt) {
var L2 = ( ((line2.x - line1.x) * (line2.x - line1.x)) + ((line2.y - line1.y) * (line2.y - line1.y)) );
if(L2 == 0) return false;
var r = ( ((pnt.x - line1.x) * (line2.x - line1.x)) + ((pnt.y - line1.y) * (line2.y - line1.y)) ) / L2;
return {
x: line1.x + (r * (line2.x - line1.x)),
y: line1.y + (r * (line2.y - line1.y))
};
}
//Returns float, the shortest distance to the (infinite) line.
function calcDistancePointToLine(line1, line2, pnt) {
var L2 = ( ((line2.x - line1.x) * (line2.x - line1.x)) + ((line2.y - line1.y) * (line2.y - line1.y)) );
if(L2 == 0) return false;
var s = (((line1.y - pnt.y) * (line2.x - line1.x)) - ((line1.x - pnt.x) * (line2.y - line1.y))) / L2;
return Math.abs(s) * Math.sqrt(L2);
}
//Returns bool, whether the projected point is actually inside the (finite) line segment.
function calcIsInsideLineSegment(line1, line2, pnt) {
var L2 = ( ((line2.x - line1.x) * (line2.x - line1.x)) + ((line2.y - line1.y) * (line2.y - line1.y)) );
if(L2 == 0) return false;
var r = ( ((pnt.x - line1.x) * (line2.x - line1.x)) + ((pnt.y - line1.y) * (line2.y - line1.y)) ) / L2;
return (0 <= r) && (r <= 1);
}
//The most useful function. Returns bool true, if the mouse point is actually inside the (finite) line, given a line thickness from the theoretical line away. It also assumes that the line end points are circular, not square.
function calcIsInsideThickLineSegment(line1, line2, pnt, lineThickness) {
var L2 = ( ((line2.x - line1.x) * (line2.x - line1.x)) + ((line2.y - line1.y) * (line2.y - line1.y)) );
if(L2 == 0) return false;
var r = ( ((pnt.x - line1.x) * (line2.x - line1.x)) + ((pnt.y - line1.y) * (line2.y - line1.y)) ) / L2;
//Assume line thickness is circular
if(r < 0) {
//Outside line1
return (Math.sqrt(( (line1.x - pnt.x) * (line1.x - pnt.x) ) + ( (line1.y - pnt.y) * (line1.y - pnt.y) )) <= lineThickness);
} else if((0 <= r) && (r <= 1)) {
//On the line segment
var s = (((line1.y - pnt.y) * (line2.x - line1.x)) - ((line1.x - pnt.x) * (line2.y - line1.y))) / L2;
return (Math.abs(s) * Math.sqrt(L2) <= lineThickness);
} else {
//Outside line2
return (Math.sqrt(( (line2.x - pnt.x) * (line2.x - pnt.x) ) + ( (line2.y - pnt.y) * (line2.y - pnt.y) )) <= lineThickness);
}
}
To see some of this code in action using a nice SVG, see this fiddle which I used to debug: https://jsfiddle.net/c06zdxtL/2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With