TomP - 4 years ago 170
Javascript Question

# Decide if a point is on (or close enough to) a line segment

I want to decide whether a mouse click point lies on an SVG polyline. I found this Python code to determine whether a point lies between two other points, and reimplemented it in JavaScript.

``````function isOnLine(xp, yp, x1, y1, x2, y2){

var p = new Point(x, y);
var epsilon = 0.01;

var crossProduct = (yp - y1) * (x2 - x1) - (xp - x1) * (y2 - y1);
if(Math.abs(crossProduct) > epsilon)
return false;
var dotProduct = (xp - x1) * (x2 - x1) + (yp - y1)*(y2 - y1);
if(dotProduct < 0)
return false;
var squaredLengthBA = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
if(dotProduct > squaredLengthBA)
return false;

return true;
}
``````

But it's not working the way I want, because I will never get the mouse pointer exactly on the line. So I need something like an "imaginary thick line" to get some margin of error:

Any ideas?

The cross product divided by the length of the line gives the distance of the point from the line. So just compare this to some threshold value:

``````function isOnLine (xp, yp, x1, y1, x2, y2, maxDistance) {
var dxL = x2 - x1, dyL = y2 - y1;  // line: vector from (x1,y1) to (x2,y2)
var dxP = xp - x1, dyP = yp - y1;  // point: vector from (x1,y1) to (xp,yp)

var squareLen = dxL * dxL + dyL * dyL;  // squared length of line
var dotProd   = dxP * dxL + dyP * dyL;  // squared distance of point from (x1,y1) along line
var crossProd = dyP * dxL - dxP * dyL;  // area of parallelogram defined by line and point

// perpendicular distance of point from line
var distance = Math.abs(crossProd) / Math.sqrt(squareLen);

return (distance <= maxDistance && dotProd >= 0 && dotProd <= squareLen);
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download