Как генерировать случайные вершины для формирования выпуклого многоугольника в C++?
Мне нужно создать набор вершин для простого выпуклого многоугольника сделать минимальный вес triangluation для этого полигоны, используя динамическое программирование , я думал о том, чтобы взять круг радиуса R, а затем взять 20 вершин движется против часовой стрелки, а затем я сформирую 20 вершин выпуклого многоугольника, но я как я могу сделать это
Как я узнаю вершину, которая лежит на окружности радиуса r ?
и есть ли другой более простой способ генерации вершин для выпуклых многоугольник, отличный от этого пути
любая помощь очень ценится
4 ответов
кстати. +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] }
-
если известно количество вершин =
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)
isavg = 0.95
... меньше2PI/N
внутри для добавления перерыва, если количество вершин достигает
N
. Если послеfor
количество вершин неN
затем пересчитать все с самого начала, потому что со случайными числами вы не можете взять его, что вы всегда нажметеN
вершины сюда !!! -
пример вывода из исходного кода выше
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]);
// ...
}
вот гибкий и эффективный способ генерации выпуклого многоугольника : -
- генерировать случайные точки на окружности в центральной точке (xc,yc)
- настроить любую точку (xi, yi) в последовательности последовательных точек
- проверьте, если (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));
}