简体   繁体   中英

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

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.

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))。

@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;

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 vABx vABx + vABy vABy, since we already have those done.

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)

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

基本上,你想要做的就是找到法线 - 也就是垂直于你的线的线 - 与你的点和线相交,然后计算沿着那条线的距离。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM