在Java中,单个点X最接近arraylist中哪一对相邻点的最佳方法是什么?

时间:2014-11-04 19:40:42

标签: java

我在arraylist(即A,B,C,D)中有2D点,可以包含任意数量的点,这些点代表串在一起的线串。

假设我有一个落在B点和C点之间的点X,我怎样才能确保该函数的输出是一个arraylist,返回点“B”和“C”(或简单地指向pointA或pointB)点“B”和“C”)给出以下两种情况:

1- Point X is closer to B than C, but still falls between B and C
2- Point X is closer to C than B, but still falls between C and B
3- Point X is closer to C than G (maybe because the line segments from the array list is oddly shaped like a U or something), but the function should return either the points C and D or C and B, depending on whichever is the closest to pointX.

我当前的代码如下,假设pointX被传递到执行以下操作的函数中:

Point pointA = null;
Point pointB = null;

int minDistance = Integer.MAX_VALUE;
for(int i = 0; i < pointlist.size(); i++) {
   int distance = pointlist.get(i).getDistanceToPoint(xPoint);
   if(distance < minDistance) {

      if(pointB != null) {
           pointB = pointA;
      }
      minDistance = distance;
      pointA = pointlist.get(i); 
   } else {
     pointB = pointA;
     pointA = pointlist.get(i);
   }
}

以上情况符合案例#1,但不符合案例#2。这样做的最佳方法是什么,使pointA等于“B”,而pointB等于“C”?如果有更好的方法,我愿意接受它。

它只是最接近pointX的两个点吗? 它不仅仅是第一个和第二个最近的点,如果点的arraylist碰巧形成U形,或者某个形状使得两个点最接近,但不一定彼此相邻,如果函数返回那两个点,这是不正确的。它应该返回最接近它的第一个点,然后返回与该点相邻的第二个点。 除非 用户可能已指定从点“4”或特定索引开始,如果第6个点是第2个最接近点,则结果将返回第6点和第5点或第7点,取决于它在哪个线段内。

1 个答案:

答案 0 :(得分:0)

因此,在评论主题中的14个评价之后,事实证明问题实际上是从一组连接的线段中找到最接近某个点X的线段。该集合恰好仅作为顶点坐标存储,但这基本上是无关紧要的。

我将使用Segment因为:Java,还因为如果要解决问题,请使用数据结构来匹配您的问题。想找一条线?使用线类。所以:让我们使用专用的类来表示一个线段,而不是一个包含2个点的ArrayList:

class Segment {
  Point p1, p2;
  public Segment(Point a, Point b) { p1=a; p2=b; }
}

ArrayList<Segment> segments = new ArrayList<Segment>();
for(int i=0, last=points.size()-1; i<last; i++) {
  segments.add(new Segment(points.get(i), points.get(i+1));
}

完成。所以,最近的部分:

Segment findClosestSegment(ArrayList<Segment> segments, Point target) {
  double dist, minDist = Double.MAX_VALUE;
  Segment minDistSegment;
  for(Segment s: segments) {
    dist = s.distanceTo(target);
    if(dist < minDist) {
      minDist = dist;
      minDistSegment = s;
    }
  }
  return minDistSegment;
}

现在我们只需要实现Segment.distanceTo(Point),这需要为( a getting the projection distance for the point to the line segment实现一些线性代数,然后( b )确保投影位于段的起点/终点内。

实际上有很多网站都有这个代码供你使用,所以我不在这里(现在非常肯定there are SO questions for that code用各种可能的语言),但确实是唯一正确的用于确定某个点与特定线段的接近程度的度量标准。