在2D区域中查找多边形

时间:2015-08-13 10:16:35

标签: java algorithm polygons

我有一个包含X个多边形的二维区域。我唯一的信息是多边形的边缘。多边形由用于Voronoi图的Fortunes算法构成。

我正在尝试在java中形成多边形列表。我的问题在于弄清楚属于多边形的边缘。我应该补充一点,我在每个多边形中都有一个点,这就是Voronoi图形成的原因。

我尝试了多种方法。我尝试计算每条边的最近点,但这会产生错误。我也尝试过斜向扫描,试图以某种方式找出边缘,它也没有用。

编辑:

每条边是一条线,它有一个x1,y1,x2和y2。我有一个边缘列表,我有一个可用的点列表,我能够绘制Voronoi图。我想要的输出是每个点我有一个边缘列表,形成点在其中的多边形的形状。

http://www.cs.wustl.edu/~pless/546/lectures/f16_voronoi.jpg

enter image description here

这是我迄今为止的例子。我只能生成这个图像,因为我知道每一行的起点和终点。我对多边形一无所知。我的目标是拥有一个形状列表,以便我可以选择我想要绘制的形状。

编辑5:

以下是我设置的测试点。我正在寻找基于它们的voronoi图。我有分开构成voronoi基础的点的线。我现在需要从这些行中制作多边形。

vals = new double[2][6];
    vals[0][0] = 150;
    vals[1][0] = 250;
    vals[0][1] = 250;
    vals[1][1] = 275;
    vals[0][2] = 300;
    vals[1][2] = 300;
    vals[0][3] = 425;
    vals[1][3] = 425;
    vals[0][4] = 425;
    vals[1][4] = 125;
    vals[0][5] = 250;
    vals[1][5] = 500;

答案中提供的要点和代码产生以下内容:

enter image description here

1 个答案:

答案 0 :(得分:0)

关于Voronoi图的一些观察(使用good ole Wikipedia作为参考):

  1. 让我们调用多边形内部的内部点" seed"。
  2. 每个多边形都有一个种子,多边形本身代表所有与种子相比更接近其他种子的点的集合。
  3. 图表边框上的边缘线段最接近一个种子。
  4. 图中边缘段(不是图中边界上的边缘段)由与两个种子距离相同的段组成。
  5. 图表边框上的多边形顶点是距离两个或更多种子的距离相同的点。一个可能的例外是边界的四个角点之一,但即使这些角点在理论上也可以与多个种子等距。
  6. 图中的多边形顶点(即不在边框上的多边形顶点)与三个或更多种子的距离相同。
  7. 所以我建议的方法是循环收集边缘片段,比较每个边缘片段的终点与种子的距离,并找出最接近的种子或种子。

    以下内容未经优化,但应符合要求,除非我误解了它们。 List<SeedPoint> seeds将拥有种子点本身以及围绕它的边缘。

    顺便说一句,我{m} ignoring precision / decimal rounding issues可能会影响逻辑。

    // Get the list of edges and seeds from wherever you are getting them.
    List<GraphEdge> edges = ...
    List<SeedPoint> seeds = ...    // Assume SeedPoint is a subclass of Point.
    
    for ( GraphEdge edge : edges )
    {
      List<SeedPoint> closestSeeds = new ArrayList<>(2);
    
      // These can safely be instantiated to the diagram's hypotenuse + 1
      double closestStartDistance = ...
      double closestEndDistance = ...
    
      // Compare the distance of all seeds to the current edge's endpoints:
      for( SeedPoint seed : seeds )
      {
        double startEdgeToSeed = seed.distanceFrom( edge.getStartPoint() );
        double endEdgeToSeed   = seed.distanceFrom( edge.getEndPoint() );
    
        /* For a seed to be tracked as closest to the edge, BOTH the edge
           end points must be as close or closer to the seed than the
           current known closest edge.
    
           CAUTION: Update this to consider decimal precision issues! */
    
        if ( startEdgeToSeed == closestStartDistance &&
             endEdgeToSeed   == closestEndDistance )
        {
          // Same closeness to the currently known closest seed.
          closestSeeds.add(seed);
        }
        else if ( startEdgeToSeed <= closestStartDistance &&
                  endEdgeToSeed   <= closestEndDistance )
        {
          /* Current seed is closer than the currently known closest seed.
             Clear previous seeds and track the current. */
          closestSeeds.clear();
          closestSeeds.add( seed );
          closestStartDistance = startEdgeToSeed;
          closestEndDistance   = endEdgeToSeed;
        }
    
      }
    
      /* At the end of the iteration, closestSeeds should have size
         of either 1 or 2.  Associate the edge to the seed or seeds
         to which it is closest. */
      for ( SeedPoint closestSeed : closestSeeds )
      {
        closestSeed.addPolygonEdge( edge );
      }
    
    }
    

    为方便起见,您可能需要一个方法,将两个点作为参数并计算它们之间的距离。在上面的代码中,somePoint.distanceFrom(someOtherPoint)是什么。

    可能还有其他方法更好,并且可能有方法优化上面的示例......