How can I tell if a point is nearby a certain line?
Asked Answered
H

7

9

I asked "How can I tell if a point belongs to a certain line?" before and I found a suitable answer so thank you very much.

Now, I would like to know how to tell if a certain point is close to my line.

Homovec answered 26/5, 2009 at 14:6 Comment(0)
D
30

You need to calculate the right angle distance to the line. Then you have to define what "close" is and test if it is within that distance.

The equation you want is:

d=|v^^·r|=(|(x_2-x_1)(y_1-y_0)-(x_1-x_0)(y_2-y_1)|)/(sqrt((x_2-x_1)^2+(y_2-y_1)^2)).

Declan answered 26/5, 2009 at 14:14 Comment(8)
Note: If you are dealing with line segments (ie not infinitely long lines), this might yield wrong results: The point might be far from the endpoints of the segment and nevertheless have a small normal distance...Derive
Also note that if you're going to turn around and compare d to D, it will be more efficient to compare |(x2 - x1) x (x1 - x0)|^2 to D^2 |x2 - x1|^2, saving two square roots and a division at the cost of a multiply.Antifriction
Thank you Mr.Alan But the link doesn't work!. I tried the equation that you put before but this give me the distance between the new point and the first point of the line not the hole line. Please Excuse me for my bad language. Sincerly, WahidHomovec
I'm not sure why the link doesn't work for you, a google search for "Point-Line Distance (2-Dimensional)" will bring it up as the first response and it goes into much more detail.Declan
In case you can't get to the link and you just want an equation to plug the numbers in, I put up the formula you want.Declan
Excuse me Mr.Alan but the formula too doesn't appear!.Homovec
The site must be blocked from your location, sorry. The formula is: abs((x2-x1)*(y1-y0)-(x1-x0)(y2-y1)) / sqrt((x2-x1)^2 + (y2-y1)^2)Declan
Is d the maximal distance allowed to determine weither a given point is on the segment or not ?Unwarrantable
A
3

@Alan Jackson's answer is almost perfect - but his first (and most up-voted) comment suggests that endpoints are not correctly handled. To ensure the point is on the segment, simply create a box where the segment is a diagonal, then check if the point is contained within. Here is the pseudo-code:

Given Line ab, comprised of points a and b, and Point p, in question:

int buffer = 25;//this is the distance that you would still consider the point nearby
Point topLeft = new Point(minimum(a.x, b.x), minimum(a.y, b.y));
Point bottomRight = new Point(maximum(a.x, b.x), maximum(a.y, b.y));
Rect box = new Rect(topLeft.x - buffer, topLeft.y - buffer, bottomRight.x + buffer, bottomRight.y + buffer);
if (box.contains(p))
{
    //now run the test provided by Alan
    if (test)
        return true;
}
return false;
Alto answered 24/3, 2014 at 15:4 Comment(0)
M
2

Here's a python function which does the trick. It should work in 2 or 3 dimensions (or more) and handles vertical and horizontal lines without special cases. If you set clipToSegment to true the returned point is clipped to the ends if the projected line extends beyond the supplied line segment.

def nearestPointOnLine(pt, r0, r1, clipToSegment = True):
    r01 = r1 - r0           # vector from r0 to r1 
    d = np.linalg.norm(r01) # length of r01
    r01u = r01 / d          # unit vector from r0 to r1
    r = pt - r0             # vector from r0 to pt
    rid = np.dot(r, r01u)   # projection (length) of r onto r01u
    ri = r01u * rid         # projection vector
    lpt = r0 + ri           # point on line

    if clipToSegment:       # if projection is not on line segment
        if rid > d:         # clip to endpoints if clipToSegment set
            return r1
        if rid < 0:
            return r0 

    return lpt

Usage: (distance of point [4,5] from the line segment from [2,4] to [4,6])

r0 = np.array([2,4])
r1 = np.array([4,6])
rpt = np.array([4,5])
pt = nearestPointOnLine(rpt, r0, r1, True)

dist = np.linalg.norm(rpt-pt)
print('dist', dist)
Manometer answered 18/11, 2017 at 14:6 Comment(1)
calculation of ri and lpt can be made right before the last returnGerontology
F
0

Basically, what you want to do it find the normal line — that is, a line perpendicular to your line — that intersects your point and the line, and then compute the distance along that line.

Ferromagnetic answered 26/5, 2009 at 14:16 Comment(2)
Yes Sir but i'm very weak in math so please help me and give me the equation for this.Homovec
See the top one. It's all there.Ferromagnetic
K
0

How close is near?

Some geometry will give you the answer you need, you just need to be aware of the following steps.

Assuming your like is of the form y=mx+b, the shortest distance to your point will be the line perpendicular to your starting line (m1=-1/m), intersecting your point in question.

From there you calculate the distance between the intersection point and the point in question.

Kasher answered 26/5, 2009 at 14:16 Comment(0)
S
0

Calculate the point on your line that is closest to that point.

Assuming the line segment is a and b, and the point is p.

float vAPx = p.x - a.x;
float vAPy = p.y - a.y;
float vABx = b.x - a.x;
float vABy = b.y - a.y;
float sqDistanceAB = a.distanceSq(b);
float ABAPproduct = vABx*vAPx + vABy*vAPy;
float amount = ABAPproduct / sqDistanceAB;
if (amount > 1) amount = 1;
if (amount < 0) amount = 0;

Which gives you 'amount', how far through the line segment you are between A and B (properly bounded).

    float nx = (amount * (b.x - a.x)) + a.x;
    float ny = (amount * (b.y - a.y)) + a.y;

Gives you point (nx,ny).

if (p.distance(nx,ny) > threshold) reject;

This will properly work beyond the end of the line segment, because it keeps 'amount' between 0 and 1.

If you don't want it a bounded line segment get rid of the bounds for amount. The rest of the code will still work, calculating positions beyond and before A and beyond B.

There was another question that claimed this question was a duplicate but, it's asking for a different thing hence my solution solves for the position of the point and then just solves the Euclidean distance (which actually solves both questions).

a.distanceSq(b) can also be done as vABxvABx + vAByvABy, since we already have those done.

Spinach answered 21/6, 2015 at 7:33 Comment(0)
I
-2

Google is your friend: Point-Line Distance (2-Dimensional). You can just use the equation at the bottom and there you go.

Isreal answered 26/5, 2009 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.