Check if the point is between two other points and at a certain distance from the line?

I want to determine if a click is made between the points and approximately on the segment of the line that connects the two points.

My question is similar to How can you tell if a point is between two other points in a line segment? but it is delayed at two points:

  • Im works in javascript and the coordinates are integer (pixels).
  • The point does not have to be exactly on the line segment. Admission required.

The following code is adapted from this answer , but I donโ€™t know how to insert tolerance on a line segment

a and b are the endpoints of the line segment, and c is the click point. I want to check if c between a and b and roughly on the segment that connects a and b

 PencilTool.prototype._isBetween = function(a,b,c){ //test if a, b and c are aligned var crossproduct = (cy - ay) * (bx - ax) - (cx - ax) * (by - ay); if(Math.abs(crossproduct) !== 0){ return false; } var dotproduct = (cx - ax) * (bx - ax) + (cy - ay)*(by - ay) if(dotproduct < 0){ return false } var squaredlengthba = (bx - ax)*(bx - ax) + (by - ay)*(by - ay); if(dotproduct > squaredlengthba){ return false; } return true; } 
+1
javascript linear-algebra algebra
Jul 10 '15 at 17:29
source share
3 answers

enter image description here

Perhaps you need this formula.

Here is a link to the wikipedia page for this formula.

This source is very thorough, but probably not the easiest to read. You can read the explanation on the wiki, but I'm going to explain it here in a different way, in the hope that I can help you and other readers visualize it.

x0 and y0 are the coordinates of the click point. x1 and y1 are the coordinates of the endpoint of your first line. x2 and y2 are the coordinates of your second endpoint on the same line.

This formula takes three sets of coordinates for three points as parameters.
The first two groups of coordinates form a line. The third parameter is your click point. It returns the distance.

Ok, now try to imagine what this formula does. So you take the click point and the two end points of the line, and you imagine a triangle. We have three points that we need to make a triangle.

therefore, to find the height of the triangle, you have a formula that is a permutation of the familiar A = (1/2) bh

enter image description here

So, when you find the height of the triangle like this, you find the distance between the click point and the line. (This is the shortest distance between the click point and the string, to be exact)

The higher distance formula above basically does this. The difference here, and why it looks more complicated, is that the part in which A is calculated is explicitly shown.

As for the tolerance you were talking about, just set a variable for the tolerance and compare the distance to that tolerance. If you want something a little more โ€œfuzzyโ€ for the allowance for clicks next to the line, you will need to do more math, but I assume that you only want to know if the click was a certain distance from the line.

When you write this function, make sure that you do good bookkeeping and set the correct coordinates in the right place, otherwise you will get a distant distance, but not what you want. Since you mentioned that you use integers, you cannot get the perfect shape back from the distance formula, I mean, look at this square root, so if you don't get the perfect int back, donโ€™t worry, just round up or down ,

+5
Jul 10 '15 at 17:53 on
source share
โ€” -

You can overlay a div between two points, rotate as necessary, and to the extent necessary. Attach CSS hover or click events in a div.

Use the distance formula to determine the width of the div:

enter image description here

Use this formula to determine the angle of rotation in degrees:

 Math.atan2((y1-y2),(x1-x2))*(180/Math.PI) 

For simplicity, I use jQuery in my fragment, but I can quickly rewrite it in vanilla JavaScript:

 var x1= 10+Math.random()*500/4, y1= 10+Math.random()*300/4, x2= Math.random()*500/2 + 500/4, y2= Math.random()*300/2 + 300/4, pt= $('.a').width()/2, dx= (x2-x1), dy= (y2-y1), angle= Math.atan2((y1-y2),(x1-x2))*(180/Math.PI), tolerance= 30; $('.a').css({left: x1, top : y1}); $('.b').css({left: x2, top : y2}); $('div.c').css({ width: Math.sqrt(dx*dx + dy*dy), height: tolerance, left: x2+pt, top: y2+pt, transformOrigin: '0px '+tolerance/4+'px', transform: 'rotate('+angle+'deg)' }); $('div.c') .click(function() { alert('clicked!'); }); 
 body { margin: 0; padding: 0; } div.a, div.b, div.c { position: absolute; border-radius: 50%; height: 1.2em; width: 1.2em; text-align: center; background: orange; } div.c { border: 1px solid #eee; background: transparent; border-radius: 0; } div.c:hover ~ div.a, div.c:hover ~ div.b { background: lightgreen; } div.c hr { position: relative; top: 50%; transform: translateY(-50%); height: 1.2em; border: none; border-top: 1px solid orange; } div.c:hover hr { border-top: 1px solid green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="c"><hr></div> <div class="a">A</div> <div class="b">B</div> 
+2
Jul 10 '15 at 18:51
source share

Here is the latest javascript function I'm using right now.

The first part uses the distance formula, as described in Ashley Tharp's answer , we first check if c at a predetermined distance ( tolerance ) of the line passing through a and b .

The second part is taken from Cyrille Ka's answer from a similar question .

Then, to find out if c between a and b , you also need to check that the point product (ba) and (ca) positive and less than the square of the distance between a and b .

 // a and b are vertices of the segment AB and c is the tested point (here from a mouseclick event (e)) var a={}, b={}, c={}; ax = 100; ay = 100; bx = 200; by = 200; cx = e.screenX cy = e.screeny if(isBetween(a,b,c, 5){ console.log(true); } isBetween = function(a,b,c, tolerance){ //test if the point c is inside a pre-defined distance (tolerance) from the line var distance = Math.abs((cy - by)*ax - (cx - bx)*ay + cx*by - cy*bx) / Math.sqrt(Math.pow((cy-by),2) + Math.pow((cx-bx),2)); if (distance > tolerance){ return false; } //test if the point c is between a and b var dotproduct = (cx - ax) * (bx - ax) + (cy - ay)*(by - ay) if(dotproduct < 0){ return false; } var squaredlengthba = (bx - ax)*(bx - ax) + (by - ay)*(by - ay); if(dotproduct > squaredlengthba){ return false; } return true; }; 
+1
Jul 13. '15 at 12:54
source share



All Articles