Как генерировать случайные вершины для формирования выпуклого многоугольника в C++?

Мне нужно создать набор вершин для простого выпуклого многоугольника сделать минимальный вес triangluation для этого полигоны, используя динамическое программирование , я думал о том, чтобы взять круг радиуса R, а затем взять 20 вершин движется против часовой стрелки, а затем я сформирую 20 вершин выпуклого многоугольника, но я как я могу сделать это

Как я узнаю вершину, которая лежит на окружности радиуса r ?

и есть ли другой более простой способ генерации вершин для выпуклых многоугольник, отличный от этого пути

любая помощь очень ценится

4 ответов


кстати. +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) ... минимальный да
    • a1=0.40*(2*M_PI/N) ... a0+(0.5*a1) is avg = 0.95 ... меньше 2PI/N

    внутри для добавления перерыва, если количество вершин достигает N. Если после for количество вершин не N затем пересчитать все с самого начала, потому что со случайными числами вы не можете взять его, что вы всегда нажмете N вершины сюда !!!

  3. пример вывода из исходного кода выше

img

PS.

вы также можете использовать эллипс, если форма круга недостаточно хороша

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

создайте свои 20 случайных чисел от 0 до 2 * pi и отсортируйте их.

теперь используйте небольшую базовую тригонометрию для преобразования в координаты X,Y.

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

вот гибкий и эффективный способ генерации выпуклого многоугольника : -

  1. генерировать случайные точки на окружности в центральной точке (xc,yc)
  2. настроить любую точку (xi, yi) в последовательности последовательных точек
  3. проверьте, если (x(i-1),y(i-1)) , (xi,yi) , (x(i+1),y(i+1)) образуют левый поворот, иначе отклоните настройку.

Если точки расположены против часовой стрелки, то левый поворот в точке (x2,y2) :-

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

if(crosspro>0) return(left_turn);

else return(right_turn);

Это моя версия метода circle в Javascript.

  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));
  }