Search if point is on line

Say I have a line drawn like this in an HTML5 Canvas:

... ctx.beginPath(); ctx.moveTo(x,y); ctx.lineTo(x1,y1); ctx.closePath(); ... 

I want to find out if a mouse event has occurred on this line, and I have this code:

 var handleMouseDown = function(e) { var coords = translateCoords(ex,ey); ... if (ctx.isPointInPath(coords.x, coords.y) { ... 

Now this code works fine for circles and rectangles, but not for lines. I have 2 questions:

  • My thinking is that maybe calling closePath () on the line itself is incorrect. Question: how can I check if a mouse event has occurred on this line?

  • How can I expand this to find if a mouse event has occurred down the line?

+3
source share
3 answers

The first step is to find the normal projection of the point on the line. This is actually quite simple: take the distance from point 1 to the target and from point 2 to the target and name them D1 and D2, respectively. Then calculate D1+(D2-D1)/2 . This is the distance to the projected point on the line from point 1.

Now you can find this point and get the distance from this point to the target. If the distance is zero, then the target is exactly on the line. If the distance is less than 5, the target was less than 5 pixels away, etc.

UPDATE: a picture is worth a thousand words. Here is the diagram:

Diagram
(source: adamhaskell.net )

(Looking back, you should probably make these circles a different color ... Also, the purple line should be perpendicular to the AB line. Blame my terrible target for the blue line!)

+7
source

Here's an approach taken from a Wikipedia article Distance from a point to a line (a line defined by two points)

  var Dx = x2 - x1; var Dy = y2 - y1; var d = Math.abs(Dy*x0 - Dx*y0 - x1*y2+x2*y1)/Math.sqrt(Math.pow(Dx, 2) + Math.pow(Dy, 2)); 

where (x0, y0) is your point coordinates, and your Line ((x1, y1), (x2, y2)) However, this does not check the boundaries of the line, so I had to add one more check.

  function inBox(x0, y0, rect) { var x1 = Math.min(rect.startX, rect.startX + rect.w); var x2 = Math.max(rect.startX, rect.startX + rect.w); var y1 = Math.min(rect.startY, rect.startY + rect.h); var y2 = Math.max(rect.startY, rect.startY + rect.h); return (x1 <= x0 && x0 <= x2 && y1 <= y0 && y0 <= y2); } 

If your line is defined as a rectangle. Hope this helps.

+2
source

You have two options. Your "simple" option is to use the canvas for this - read the pixel data wherever there is a mouse, and if it has the same color as your line, then the user clicked on the line. However, this makes a lot of assumptions, since everything on your canvas is displayed in a different solid color. However, this is possible because the general trick is to do everything on the screen outside of another solid color. Then, when the user clicks something, you know exactly what it is by reading the color of that one pixel and matching it with the original object.

But this is not exactly what you asked :)

You do not want to know if the user clicked a row because they almost never will. The line is infinitely thin, so if it is not exactly horizontal or vertical, it will never click on it. Instead, you want to see how far the mouse is from the line. Kolink answered this part, so I will stay here :)

+1
source

All Articles