如何在c ++中生成随机顶点以形成凸多边形?

时间:2014-02-10 23:24:06

标签: c++ algorithm computational-geometry

我需要为一个简单的凸多边形生成一组顶点,以便使用动态编程对该多边形进行最小权重三角化,我考虑采用半径为r的圆,然后采用20个顶点逆时针方向移动然后我将形成一个20顶点凸多边形,但我怎么能这样做

我怎么知道位于半径为r的圆上的顶点?

并且还有另一种更简单的方法来生成除此之外的凸多边形顶点

任何帮助非常感谢

4 个答案:

答案 0 :(得分:8)

生成0到2 * pi之间的20个随机数,并对它们进行排序。

现在使用一点基本三角函数转换为X,Y坐标。

for (int i = 0; i < 20; i++)
{
    x = x0 + r*cos(angle[i]);
    y = y0 + r*sin(angle[i]);
    // ...
}

答案 1 :(得分:6)

顺便说一句。 +1用这个圆圈很好的方法...

  1. 不关心顶点的数量

    {
    double x0=50.0,y0=50.0,r=50.0;  // circle params
    double a,da,x,y;
    // [view]                       // my view engine stuff can skip this
    glview2D::_lin l;
    view.pic_clear();
    l.col=0x00FFFFFF;
    // [/view]
    for (a=0.0;a<2.0*M_PI;)         // full circle
        {
        x=x0+(r*cos(a));
        y=y0+(r*sin(a));
        a+=(20.0+(40.0*Random()))*M_PI/180.0;              // random angle step < 20,60 > degrees
    
        // here add your x,y point to polygon
    
        // [view]                   // my view engine stuff can skip this
        l.p0=l.p1;                  // just add line (lust x,y and actual x,y)
        l.p1.p[0]=x;
        l.p1.p[1]=y;
        view.lin.add(l);
        // [/view]
        }
    // [view]                   // my view engine stuff can skip this
    view.lin[0].p0=l.p1;        // just join first and last point in first line (was point0,point0)
    // [view]
    }
    
  2. 如果已知顶点数= N

    将随机步骤设置为平均值小于2PI / N,例如:

    da=a0+(a1*Random());
    
    • a0=0.75*(2*M_PI/N) ... minimal da
    • a1=0.40*(2*M_PI/N) ... a0+(0.5*a1)avg = 0.95 ...少于2PI/N

    如果顶点数达到N,则添加中断。如果for之后顶点数不是N,那么从头开始重新计算所有因为随机数你无法接受它总是以这种方式点击N顶点!!!

    < / LI>
  3. 上面源代码的示例输出

  4. img

    <强> PS。

    如果圆形不够好,也可以使用椭圆

    x=x0+(rx*cos(a));
    y=y0+(ry*sin(a));
    
    • rx != ry

答案 2 :(得分:3)

这是一种灵活有效的生成凸多边形的方法: -

  
      
  1. 在圆心处生成中心点(xc,yc)的随机点
  2.   
  3. 按连续点的顺序调整任何点(xi,yi)
  4.   
  5. 检查是否(x(i-1),y(i-1)),(xi,yi),(x(i + 1),y(i + 1))形成左转,否则拒绝调整
  6.   

如果点以逆时针方式排列,则在(x2,y2)点左转: -

int crosspro = (x3-x2)*(y2-y1) - (y3-y2)*(x2-x1) 

if(crosspro>0) return(left_turn);

else return(right_turn);

答案 3 :(得分:1)

这是我在Javascript中使用circle方法的版本。

  var x = [0];
  var y = [0];
  var r = 0;
  var angle = 0
  for (var i = 1; i < 20; i++) {
    angle += 0.3 + Math.random() * 0.3
    if (angle > 2 * Math.PI) {
      break; //stop before it becomes convex
    } 
    r = (5 + Math.random() * 20+Math.random()*50)
    x.push(x[i - 1] + r * Math.cos(angle));
    y.push(y[i - 1] + r * Math.sin(angle));
  }