如何赋予有限边缘无限的优势?

Jun*_*Jun 7 c++ boost voronoi

我发现在boost库中,对于voronoi图,一些边缘数据是无限的.根据指示,它必须被剪裁.但我无法找到如何做到这一点.请问有人可以给我一个示例代码吗?

谢谢

Edw*_*use 6

这是一个相当陈旧的问题,但我在尝试解决完全相同的问题时发现了它.分享我所遇到的解决方案是公平的,所以下一个可怜的傻瓜不必自己搞清楚.

我不知道这是否是一种特别好的做事方式,我怀疑如果你开始使用弯曲的细胞会很困难,但它对我的目的来说是可行的.

基本问题是你只有一个顶点用于无限边,所以你必须自己计算方向向量.使用的方向垂直于由边缘分隔的两个点之间的矢量.

#include <vector>
#include <boost/polygon/voronoi.hpp>
using boost::polygon::voronoi_builder;
using boost::polygon::voronoi_diagram;

typedef boost::polygon::point_data<int> point;
typedef voronoi_diagram<double>::cell_type cell_type;
typedef voronoi_diagram<double>::edge_type edge_type;
typedef voronoi_diagram<double>::vertex_type vertex_type;

int main(int argc, char *argv[])
{
   std::vector<point> points;

   // Populate with random points
   for (int i = 0; i < 50; i++)
   {
      points.push_back(point(60 + rand() % 500, 60 + rand() % 500));
   }

   voronoi_diagram<double> vd;
   construct_voronoi(points.begin(), points.end(), &vd);

   // vd now contains the voronoi diagram. Let's visualise it
   // pseudocode 'draw_line(x1, y1, x2, y2)'

   for (voronoi_diagram<double>::const_cell_iterator it = vd.cells().begin();
        it != vd.cells().end(); ++it)
   {
      const cell_type& cell = *it;
      const edge_type* edge = cell.incident_edge();

      do
      {
         if (edge->is_primary())
         {
            // Easy finite edge case
            if (edge->is_finite())
            {
               // Without this check each edge would be drawn twice
               // as they are really half-edges
               if (edge->cell()->source_index() < 
                   edge->twin()->cell()->source_index())
               {
                  draw_line(edge->vertex0()->x(), edge->vertex0()->y(),
                            edge->vertex1()->x(), edge->vertex1()->y());
               }
            }
            else
            {
               // This covers the infinite edge case in question.
               const vertex_type* v0 = edge->vertex0();
               // Again, only consider half the half-edges, ignore edge->vertex1()
               // to avoid overdrawing the lines
               if (v0)
               {
                  // Direction of infinite edge if perpendicular to direction
                  // between the points owning the two half edges. 
                  // Take the rotated right vector and multiply by a large 
                  // enough number to reach your bounding box
                  point p1 = points[edge->cell()->source_index()];
                  point p2 = points[edge->twin()->cell()->source_index()];
                  int end_x = (p1.y() - p2.y()) * 640;
                  int end_y = (p1.x() - p2.x()) * -640;

                  draw_line(v0->x(), v0->y(),
                            end_x, end_y);
               }
            }
         }
         edge = edge->next();
      } while (edge != cell.incident_edge());
   }
}
Run Code Online (Sandbox Code Playgroud)