简体   繁体   English

查找离线最远的点

[英]Find point farthest from line

I have an array of points, as well as two more points (A and B). 我有一系列要点,还有两个要点(A和B)。 The last two points form a line, and I'm trying to find which of the points in my array are furthest from the line. 最后两个点形成一条线,我试图找出数组中哪些点距该线最远。 How would I do this in Java? 我将如何用Java做到这一点?

I'm wondering if it's something along the lines of finding the distance from A and B, but that doesn't sit well in my head. 我想知道这是否与找到A和B的距离相似,但这在我脑海中并不理想。

Additional info: I think it's a line segment. 附加信息:我认为这是一个线段。 Given this is QuickHull, I don't know if it makes a difference. 鉴于这是QuickHull,我不知道它是否有所作为。 I've never been the greatest when it comes to math and formulas, so more explanation is better. 在算术和公式方面,我从来都不是最出色的,所以更多的解释会更好。 Thanks! 谢谢!

Note that each 3 points [a,b,p] for each p in the array form a trianle, whose area is denoted by: (ab) * h /2 [where h is the distance from p to ab ] 请注意,数组中每个p每个3个点[a,b,p]形成一个三角形,其面积表示为: (ab) * h /2 [其中h是从pab的距离]

You can compute the area these trianles create, and select the minimal . 您可以计算这些三角创建的面积 ,然后选择 Minimum。 Since ab is constant for all - it guarantees that the trianle with the minimal area will also have the minimal h . 由于ab对于所有元素都是恒定的,因此可以保证面积最小的trianle的h也最小。

You can find it [the area of each triangle] using 您可以使用以下方法找到[每个三角形的面积]

T=(1/2)* abs((x_a - x_p) * (y_b-y_a) - (x_a - x_b)* (y_p - y_a))

[where x_a,x_b,x_p and y_a,y_b,y_p are the x,y coordinates of a,b,p respectively]. [其中x_a,x_b,x_py_a,y_b,y_p分别是a,b,px,y坐标]。

  • Though I find this method very elegant, I believe there are better ways to do it. 尽管我觉得这种方法非常优雅,但我相信有更好的方法可以做到这一点。
    ArrayList<Point> points=new ArrayList();//YOUR POINTS


    Point a=new Point(1,1);
    Point b=new Point(1,1);
    Point ABcenter=new Point((a.x+b.x)/2,(a.y+b.y)/2);//THE CENTER OF THE A AND B POINTS ,USE A OR B IF YOU WANT
    int furthestid=0;
    float furthestdis=0;
    for(int c=0;c<points.size();c++)
    {
        if(calculate_distance(ABcenter.x,ABcenter.y,points.get(c).x,points.get(c).y)>furthestdis)
        {
            furthestid=c;
        }
    }

//closestid  now contains the id of the furthest point ,use it like this points.get(c).x ...




public static double calculate_distance (float x1,float y1,float x2 ,float y2){
        return Math.sqrt((((x1-x2) * (x1-x2)) + ((y1- y2) * (y1- y2))));
}

I'm assuming you talking about line segment not line. 我假设您是在谈论线段而不是线。 First you should find your points distance from your line segment, and you can do it, as the way suggested in this similar question , after that find minimum/maximum distance over all inputs. 首先,您应该找到与线段的距离,然后按照类似问题中的建议进行操作,然后在所有输入上找到最小/最大距离。

Edit: Also from this top coder article you can find distance simply: 编辑:同样从这篇顶级编码器文章中,您可以简单地找到距离:

//Compute the dot product AB ⋅ BC
int dot(int[] A, int[] B, int[] C){
    AB = new int[2];
    BC = new int[2];
    AB[0] = B[0]-A[0];
    AB[1] = B[1]-A[1];
    BC[0] = C[0]-B[0];
    BC[1] = C[1]-B[1];
    int dot = AB[0] * BC[0] + AB[1] * BC[1];
    return dot;
}
//Compute the cross product AB x AC
int cross(int[] A, int[] B, int[] C){
    AB = new int[2];
    AC = new int[2];
    AB[0] = B[0]-A[0];
    AB[1] = B[1]-A[1];
    AC[0] = C[0]-A[0];
    AC[1] = C[1]-A[1];
    int cross = AB[0] * AC[1] - AB[1] * AC[0];
    return cross;
}
//Compute the distance from A to B
double distance(int[] A, int[] B){
    int d1 = A[0] - B[0];
    int d2 = A[1] - B[1];
    return sqrt(d1*d1+d2*d2);
}
//Compute the distance from AB to C
//if isSegment is true, AB is a segment, not a line.
double linePointDist(int[] A, int[] B, int[] C, boolean isSegment){
    double dist = cross(A,B,C) / distance(A,B);
    if(isSegment){
        int dot1 = dot(A,B,C);
        if(dot1 > 0)return distance(B,C);
        int dot2 = dot(B,A,C);
        if(dot2 > 0)return distance(A,C);
    }
    return abs(dist);
}

I think code has self explanation, if you are familiar with basic geometry, but if you aren't familiar, you should to read the article, if there is any problem for you we can help you. 我认为代码具有自我解释能力,如果您熟悉基本的几何图形,但是如果您不熟悉,则应该阅读本文,如果有任何问题,我们可以为您提供帮助。

I'm assuming you mean the Euclidean distance. 我假设您的意思是欧几里得距离。 If you're working in the plane, then the answer is simple. 如果您是在飞机上工作,那么答案很简单。

First, compute the equation of the line in the form 首先,以以下形式计算直线方程

ax + by + c = 0

In slope-intercept form, this is the same as 在斜率截距形式中,这与

y = (-a/b)x + (-c/b)

Now compute the distance from any point (p,q) to the line by 现在计算下任意点(p,q)到直线的距离

|a*p + b*q + c| / (a^2 + b^2)^(1/2)

For more than 2 dimensions, it's probably easiest to think in terms of parametrized vectors. 对于2个以上的维度,从参数化向量的角度考虑可能是最容易的。 This means think of points on the line as 这意味着将线上的点视为

p(t) = (A1 + (B1-A1)*t, A2 + (B2-A2)*t, ..., An + (Bn-An)*t)

where the two points are A = (A1,...,An) and B = (B1,...,Bn) . 其中两个点是A = (A1,...,An)B = (B1,...,Bn) Let X = (X1,...,Xn) be any other point. X = (X1,...,Xn)为任意其他点。 Then the distance between X and p(t) , the point on the line corresponding to t , is the square root of 然后之间的距离Xp(t)在对应于所述线的点t ,是的平方根

[(A1-X1) + (B1-A1)t]^2 + ... + [(An-Xn) + (Bn-An)t]^2

The distance to the line is the distance to p(t) where t is the unique value minimizing this distance. 到线的距离是到p(t)的距离,其中t是使该距离最小的唯一值。 To compute that, just take the derivative with respect to t and set it to 0 . 要计算该值,只需对t取导数并将其设置为0 It's a very straightforward problem from here, so I'll leave that bit to you. 从这里开始这是一个非常简单的问题,所以我会留给您。

If you want a further hint, then check out this link for the 3-dimensional case which reduces nicely. 如果您想要进一步的提示,请查看此链接以了解3维大小写的情况,该情况会大大减少。

I quick Google search worked well. 我快速的Google搜索效果很好。

http://www.codeguru.com/forum/printthread.php?t=194400 http://www.codeguru.com/forum/printthread.php?t=194400

If the problem is as you have stated it, you can't do much better then computing the distance for each point and choosing the smallest of these. 如果问题是您所说的,那么您不能做的更好,那就是计算每个点的距离并选择最小的距离。

However you can simplify the calculation of the distance a bit by using a generalized line equation for the line passing through A and B. This would be an equation of the form ax + by + c = 0 但是,您可以通过对穿过A和B的线使用广义线方程来简化距离的计算。这将是ax + by + c = 0形式的方程

You can compute such equation for a line passing through two arbitrary points quite easily: 您可以很容易地计算出穿过两个任意点的直线的等式:

x * (Ay - By) + y * (Bx - Ax) + Ax * By - Ay * Bx , x * (Ay - By) + y * (Bx - Ax) + Ax * By - Ay * Bx

ie a = Ay - By , b = Bx - Ax and c = Ax * By - Ay * Bx a = Ay - Byb = Bx - Axc = Ax * By - Ay * Bx

Now that you have computed such equation for the line, you can compute the distance from an arbitrary point P in the plane to the line a * x + b * y + c by substituting x and y with the coordinates of P: 现在,您已经为直线计算了这样的方程式,您可以通过用x和y替换为P的坐标来计算平面中任意点P到直线a * x + b * y + c的距离:

abs(a * Px + b * Py + c) / sqrt(a * a + b * b) . abs(a * Px + b * Py + c) / sqrt(a * a + b * b) But as the denominator will be the same for all points, you may igonore it and simply choose the point for which abs(a * Px + b * Py + c) is smallest 但是由于所有分母的分母都相同,因此您可以忽略它,而只需选择abs(a * Px + b * Py + c)最小的点

Here is a link that explains how to compute 2-d distance to a line once you have it's generalized equation. 这是一个链接 ,该链接解释了一旦有了广义方程,便如何计算到一条线的二维距离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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