如何判断一个点是否在某条线附近?

发布于 2024-07-22 20:51:14 字数 215 浏览 1 评论 0原文

我问“我如何判断是否一个点属于某条线?”之前,我找到了一个合适的答案,非常感谢。

现在,我想知道如何判断某个点是否接近我的线。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

才能让你更想念 2024-07-29 20:51:14

@Alan Jackson 的答案几乎是完美的 - 但他的第一个(也是投票最多的)评论表明端点没有得到正确处理。 为了确保该点位于线段上,只需创建一个框,其中该线段是对角线,然后检查该点是否包含在其中。 下面是伪代码:

给定线 ab,由点 a 和 b 以及点 p 组成,如下所示:

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;

@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;
牵你的手,一向走下去 2024-07-29 20:51:14

您需要计算到直线的直角距离。 然后您必须定义什么是“接近”并测试它是否在该距离内。

您想要的方程是:

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

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

抠脚大汉 2024-07-29 20:51:14

基本上,您想要做的就是找到与您的点和线相交的法线(即垂直于您的线的线),然后计算沿该线的距离。

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.

鸵鸟症 2024-07-29 20:51:14

这是一个可以解决这个问题的 python 函数。 它应该在 2 或 3 维(或更多)维中工作,并处理垂直和水平线,没有特殊情况。 如果将 clipToSegment 设置为 true,则当投影线延伸超出提供的线段时,返回的点将被剪裁到末端。

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

用法:(点[4,5]距[2,4]到[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)

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)
栀子花开つ 2024-07-29 20:51:14

近到什么程度呢?

一些几何学会给你你需要的答案,你只需要注意以下步骤。

假设您的喜欢的形式为 y=mx+b,到您的点的最短距离将是垂直于您的起始线 (m1=-1/m) 的线,与您所讨论的点相交。

从那里您可以计算交点和相关点之间的距离。

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.

嘦怹 2024-07-29 20:51:14

计算线上最接近该点的点。

假设线段为a、b,点为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;

这给你“量”,即你在 A 和 B 之间的线段有多远(正确的边界)。

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

给你点(nx,ny)。

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

这将正确地超出线段的末尾,因为它将“金额”保持在 0 和 1 之间。

如果您不希望它是有界线段,请摆脱金额的界限。 代码的其余部分仍然可以工作,计算 A 之外和之前以及 B 之外的位置。

还有另一个问题声称这个问题是重复的,但是,它要求不同的东西,因此我的解决方案解决了点的位置,然后只是解决了欧几里德距离(实际上解决了这两个问题)。

a.distanceSq(b) 也可以作为 vABxvABx + vAByvABy 完成,因为我们已经完成了这些。

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.

无所谓啦 2024-07-29 20:51:14

Google 是您的朋友:点线距离(二维)。 您只需使用底部的方程式即可。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文