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

时间:2009-05-26 14:06:58

标签: c# algorithm geometry gdi+ drawing

之前我问过“How can I tell if a point belongs to a certain line?”,我找到了合适的答案,非常感谢你。

现在,我想知道如何确定某个点关闭到我的行。

7 个答案:

答案 0 :(得分:26)

你需要calculate the right angle distance到该行。然后你必须定义“关闭”是什么,并测试它是否在该距离内。

你想要的等式是:

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

Google是您的朋友:Point-Line Distance (2-Dimensional)。您可以使用底部的等式,然后就可以了。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

附近有多近?

某些几何体将为您提供所需的答案,您只需要了解以下步骤即可。

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

从那里计算交叉点与相关点之间的距离。

答案 5 :(得分:0)

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

假设线段是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;

这会给你&#39;金额&#39;,你在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;

这将在线段结束后正常工作,因为它可以保持&#39;数量&#39;介于0和1之间。

如果你不想要它,那么有界线段可以摆脱金额的限制。其余的代码仍然可以工作,计算A之前和之后的位置。

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

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

答案 6 :(得分:0)

这是一个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)