如何在C ++中绘制多边形,使得线不相交?

时间:2011-11-23 00:03:36

标签: c++ polygon computational-geometry

我需要在C ++中绘制一个多边形。我在矢量中设置随机点,然后通过线连接它们。但有时这些线相交,我得到这样的东西。

enter image description here

是否有任何公式或类似的东西,以便线条不会交叉?

以下是代码的一部分:

void draw_picture(Canvas & canvas) {
  PairXY a,b,c,d,e;
  int k;
  vector <PairXY> vertex;
  vertex.push_back(PairXY(drandom(k),drandom(k)));
  vertex.push_back(PairXY(drandom(k),drandom(k)));
  vertex.push_back(PairXY(drandom(k),drandom(k)));
  vertex.push_back(PairXY(drandom(k),drandom(k)));
  vertex.push_back(PairXY(drandom(k),drandom(k)));

  vector <PairXY>::const_iterator iter;

  iter = vertex.begin();
  a=*iter;
  iter = vertex.begin()+1;
  b=*iter;
  iter = vertex.begin()+2;
  c=*iter;
  iter = vertex.begin()+3;
  d=*iter;
  iter = vertex.begin()+4;
  e=*iter;

  Line l1(a,b);
  draw_line(l1,canvas);
  Line l2(b,c);
  draw_line(l2,canvas);
  Line l3(c,d);
  draw_line(l3,canvas);
  Line l4(d,e);
  draw_line(l4,canvas);
  Line l5(e,a);
  draw_line(l5,canvas);
}

3 个答案:

答案 0 :(得分:4)

听起来像是想要convex hull

就计算它们而言,你有several options

我对the monotone chain algorithm祝你好运。

答案 1 :(得分:2)

听起来你可能正在寻找的是“简单”(而非“复杂”)多边形:

http://en.wikipedia.org/wiki/Simple_polygon

对此并不一定是唯一的解决方案:

Sort point list into polygon

这就是为什么点或路径段的排序通常在多边形绘制引擎中很重要。如果您如此倾向 - 但是 - 您可以为一组点找到至少一个非复杂多边形:

http://www.computational-geometry.org/mailing-lists/compgeom-announce/2003-March/000727.html

http://www.computational-geometry.org/mailing-lists/compgeom-announce/2003-March/000732.html


其他人已经指出你的代码是重复的。您也没有在共享的摘录中定义k,最好对对象矢量(“顶点”)使用复数项,而不是建议它是单数(“顶点”)。这是一组相当简单易懂的变化,应该推广到任意数量的顶点:

void draw_picture(Canvas & canvas, int k, int numVertices = 5) {
  vector<PairXY> vertices;
  for (int index = 0; index < numVertices; index++) { 
      vertices.push_back(PairXY(drandom(k),drandom(k)));
  }

  vector<PairXY>::const_iterator iter = vertices.begin();
  while (iter != vertices.end()) {
     PairXY startPoint = *iter;
     iter++;
     if (iter == vertices.end()) {
         Line edgeLine (startPoint, vertices[0]);
         draw_line(edgeLine, canvas);
     } else {
         Line edgeLine (startPoint, *iter);
         draw_line(edgeLine, canvas);
     }
   }
}

有许多方法可以管理C ++中的迭代,尽管其中许多方法比其他语言中的对应方式更冗长。最近在C ++ 11中添加了一个很好的range-based for loop,但你的构建环境可能还不支持它。

答案 2 :(得分:0)

在绘制数组之前对其进行排序

找到最左边的点 而不是从那里去CCW

即 最左边的点y&lt;第一点y直到找不到

最右边的点,直到找不到