代码之家  ›  专栏  ›  技术社区  ›  Wahid Bitar

我怎样才能知道一个点是否在某条线附近?

  •  6
  • Wahid Bitar  · 技术社区  · 16 年前

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

    现在,我想知道如何判断某一点 关闭 对我来说。

    7 回复  |  直到 8 年前
        1
  •  26
  •   flaviut    8 年前

    您需要 Calculate the right angle distance to the line.然后,您必须定义“关闭”是什么,并测试它是否在该距离内。

    您需要的公式是:

    排队。然后你必须定义什么是“接近”,并测试它是否在这个距离内。

    您需要的公式是:

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

        2
  •  2
  •   Community Mohan Dere    8 年前

    @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;
    
        3
  •  0
  •   n3rd    16 年前

    谷歌是你的朋友: Point-Line Distance (2-Dimensional) . 你只要用下面的方程就可以了。

        4
  •  0
  •   Charlie Martin    16 年前

    基本上,你想做的就是找到一条垂直于你的线的线,它与你的点和线相交,然后计算沿着这条线的距离。

        5
  •  0
  •   Ian Jacobs    16 年前

    离这儿有多远?

    有些几何图形会给出你需要的答案,你只需要知道以下步骤。

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

    从这里你可以计算出交叉点和相关点之间的距离。

        6
  •  0
  •   Tatarize    10 年前

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

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

    这将在测线段末端之外正常工作,因为它将“amount”保持在0和1之间。

    如果您不希望它是一个有界的线段,请去掉数量的边界。代码的其余部分仍将工作,计算a之前、a之后和b之后的位置。

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

    a.距离sq(b)也可以作为vabx VABX+VABY 瓦比,因为我们已经完成了。

        7
  •  0
  •   Andrew    8 年前

    下面是一个python函数,它可以实现这个技巧。它应在2或3维(或更多)的工作,处理垂直和水平线,无特殊情况。如果你设置 clipToSegment 如果投影线超出提供的线段,则返回的点将被剪裁到端点。

    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)