任意多边形顶点排序和凸包计算

1,理论

凸包计算算法导论上有讲,关键步骤是根据对顶点进行逆时针排序。凸包顶点只是多边形顶点子集。

任意多边形顶点排序和凸包计算_第1张图片

图-1

如图1中,判断三个点构成顺时针还是逆时针方向。使用向量点积即可:

向量A

向量B

A.dot(B) 是一个实数,大于0,则逆时针,小于0则顺时针。

2,效果图:

任意多边形顶点排序和凸包计算_第2张图片

图 - 2

任意多边形顶点排序和凸包计算_第3张图片

图 - 3

图2是随机生成了三十个点。

图3是黄色线条是排序以后顺序链接,外面淡蓝色线条是凸包。注意排序以后的顶点只保证顺序连线的顺序,不能保证所有顶点逆时针/顺时针排序。。。而且中间非常有可能是z型,即顺时针/逆时针翻转~

 

3,可运行程序

freeglut2.6.0

#include #include #include void drawLine(const POINT& pnt1, const POINT& pnt2) { glBegin(GL_LINES); glVertex2f(pnt1.x, pnt1.y); glVertex2f(pnt2.x, pnt2.y); glEnd(); } /****************************************************************************** 判断三个点构成逆时针/顺时针方向 r = multiply(begPnt, endPnt, nextPnt),得到(nextPnt-begPnt)*(endPnt-begPne)的叉积 r>0: nextPnt在矢量的逆时针方向 r=0: opspep三点共线 r<0: ep在矢量的顺时针方向 *******************************************************************************/ double multiply(POINT begPnt,POINT endPnt,POINT nextPnt) { return((nextPnt.x-begPnt.x)*(endPnt.y-begPnt.y) - (endPnt.x-begPnt.x)*(nextPnt.y-begPnt.y)); } double distance(const POINT& pnt1, const POINT& pnt2) { return sqrtf( (pnt2.x-pnt1.x) * (pnt2.x-pnt1.x) + (pnt2.y-pnt1.y) * (pnt2.y-pnt1.y) ); } void Graham_scan(POINT PointSet[], POINT ch[], int n, int &len) { int i,j,k=0,top=2; POINT tmp; // 选取PointSet中y坐标最小的点PointSet[k],如果这样的点有多个,则取最左边的一个 for(i=1;i0 || // 极角更小 (multiply(PointSet[j], PointSet[k], PointSet[0])==0) && /* 极角相等,距离更短 */ distance(PointSet[0], PointSet[j]) < distance(PointSet[0], PointSet[k]) ) k=j; tmp = PointSet[i]; PointSet[i] = PointSet[k]; PointSet[k] = tmp; } ch[0] = PointSet[0]; ch[1] = PointSet[1]; ch[2] = PointSet[2]; for (i = 3; i=0) top--; ch[++top] = PointSet[i]; } len = top+1; } const int gNUM = 30; POINT gTrackPath[gNUM]; POINT gSortedPath[gNUM]; POINT gConvex[gNUM]; bool gChange = false; void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); srand( (unsigned)time( NULL ) ); // 随机初始化点 for (int i=0; i

你可能感兴趣的:(OpenGL,C++,算法)