CGAL编程实现点集的Delaunay三角剖分和Voronoi图

转自: http://blog.csdn.net/jinzhilong580231/article/details/6746533

//使用CGAL编程实现点集的Delaunay三角剖分,voronoi图
//如果对Delaunay算法本身关注,请参考CGAL对Delaunay三角剖分的实现,CGAL对Delaunay三角剖分的实现是增量算法(Incremental)
//本程序的重点在于对CGAL中Delaunay数据结构的访问,请参考函数points_triangulation()。初次使用CGAL,不妥之处请多指正,谢谢。

//SudoLeo 2010/7/20
//CGAL required, GLUT required

 

 

[cpp]  view plain copy
  1. //使用CGAL编程实现点集的Delaunay三角剖分,voronoi图  
  2. //如果对Delaunay算法本身关注,请参考CGAL对Delaunay三角剖分的实现,CGAL对Delaunay三角剖分的实现是增量算法(Incremental)  
  3. //本程序的重点在于对CGAL中Delaunay数据结构的访问,请参考函数points_triangulation()  
  4.   
  5. //SudoLeo 2010/7/20  
  6. //CGAL required, GLUT required  
  7.   
  8. #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>  
  9. #include <CGAL/Triangulation_euclidean_traits_xy_3.h>  
  10. #include <CGAL/Delaunay_triangulation_2.h>  
  11. #include <GL/glut.h>  
  12. #include <iostream>  
  13. #include <cmath>  
  14.   
  15. typedef CGAL::Exact_predicates_inexact_constructions_kernel K;  
  16. typedef CGAL::Delaunay_triangulation_2<K> Delaunay;  
  17. typedef Delaunay::Vertex_handle Vertex_handle;  
  18.   
  19. typedef K::Point_2 Point;  
  20.   
  21. std::vector<Point> vertices;  
  22.   
  23. int global_w, global_h;  
  24. int tri_state = 0;  
  25.   
  26. void points_draw()  
  27. {  
  28. glClear(GL_COLOR_BUFFER_BIT);  
  29. glPushMatrix();  
  30.   
  31. std::vector <Point>::iterator iter;  
  32. glColor3f( 1.0, 1.0, 1.0 );  
  33. glPointSize(5);  
  34. glBegin(GL_POINTS);  
  35. for( iter = vertices.begin(); iter != vertices.end(); iter++ )  
  36. glVertex2i( iter->hx(), iter->hy() );  
  37. glEnd();  
  38.   
  39. glPopMatrix();  
  40. glutSwapBuffers();  
  41. }  
  42.   
  43. void points_add_point( int x, int y )  
  44. {   
  45. vertices.push_back( Point( x, global_h-y ) );  
  46. }  
  47.   
  48.   
  49. void points_clear()  
  50. {  
  51. glClear(GL_COLOR_BUFFER_BIT);  
  52. glPushMatrix();  
  53. glPopMatrix();  
  54. glutSwapBuffers();  
  55.   
  56. vertices.clear();  
  57. tri_state = 0;  
  58. }  
  59.   
  60. void read_file()//从文件中读入点集数据,调试时所使用  
  61. {  
  62. FILE* f;  
  63. f = freopen( "data.txt""r", stdin );  
  64.   
  65. int a,b;  
  66. while(std::cin>>a >> b)  
  67. {  
  68. vertices.push_back( Point( a, b ) );  
  69. }  
  70.   
  71. fclose(f);  
  72. }  
  73.   
  74. void points_triangulation()  
  75. {  
  76. Delaunay dt;//Delaunay数据结构,代表当前数据的一个且仅有一个的三角剖分,详情请参考CGAL_manual  
  77.   
  78. dt.insert(vertices.begin(), vertices.end());//输入数据  
  79.   
  80. points_draw();//points_draw()函数中已经调用一次glutSwapBuffers(),本函数再一次调用glutSwapBuffers()  
  81. //在一帧的绘制中两次调用glutSwapBuffers(),虽对本例无影响,但存在一些问题,这不是本文的重点,可暂且忽略之  
  82.   
  83. glPushMatrix();  
  84.   
  85. Delaunay::Finite_faces_iterator fit;//遍历Delaunay的所有面(有限面),将每个面的边画出来  
  86. glColor3f( 0.0, 0.0, 1.0 );  
  87. for( fit = dt.finite_faces_begin(); fit != dt.finite_faces_end(); fit ++)  
  88. {  
  89. glBegin(GL_LINE_LOOP);  
  90. glVertex2i( fit->vertex(0)->point().hx(), fit->vertex(0)->point().hy() );  
  91. glVertex2i( fit->vertex(1)->point().hx(), fit->vertex(1)->point().hy() );  
  92. glVertex2i( fit->vertex(2)->point().hx(), fit->vertex(2)->point().hy() );  
  93. glEnd();  
  94. }//完成Delaunay三角剖分的绘制,Delaunay图  
  95.   
  96. Delaunay::Edge_iterator eit;//遍历Delaunay的所有边,绘制Delaunay图的对偶图,即Voronoi图  
  97.   
  98. glEnable( GL_LINE_STIPPLE );//使用点画模式,即使用虚线来绘制Voronoi图  
  99. glLineStipple( 1, 0x3333 );  
  100. glColor3f( 0.0, 1.0, 0.0 );  
  101.   
  102. for( eit = dt.edges_begin(); eit != dt.edges_end(); eit ++)  
  103. {  
  104. CGAL::Object o = dt.dual(eit);//边eit在其对偶图中所对应的边  
  105.   
  106. if (CGAL::object_cast<K::Segment_2>(&o)) //如果这条边是线段,则绘制线段  
  107. {  
  108. glBegin(GL_LINES);  
  109. glVertex2i( CGAL::object_cast<K::Segment_2>(&o)->source().hx(), CGAL::object_cast<K::Segment_2>(&o)->source().hy() );  
  110. glVertex2i( CGAL::object_cast<K::Segment_2>(&o)->target().hx(), CGAL::object_cast<K::Segment_2>(&o)->target().hy() );  
  111. glEnd();  
  112. }  
  113. else if (CGAL::object_cast<K::Ray_2>(&o))//如果这条边是射线,则绘制射线  
  114. {  
  115. glBegin(GL_LINES);  
  116. glVertex2i( CGAL::object_cast<K::Ray_2>(&o)->source().hx(), CGAL::object_cast<K::Ray_2>(&o)->source().hy() );  
  117. glVertex2i( CGAL::object_cast<K::Ray_2>(&o)->point(1).hx(), CGAL::object_cast<K::Ray_2>(&o)->point(1).hy() );  
  118. glEnd();  
  119. }  
  120. }  
  121. glDisable( GL_LINE_STIPPLE );//关闭点画模式  
  122.   
  123. glPopMatrix();  
  124. glutSwapBuffers();  
  125.   
  126. tri_state = 1;//完成三角剖分,置状态为1  
  127. }  
  128.   
  129. void display(void)  
  130. {  
  131. }  
  132.   
  133. void init(void)   
  134. {  
  135. glClearColor (0.0, 0.0, 0.0, 0.0);  
  136. glShadeModel (GL_FLAT);  
  137.   
  138. }  
  139.   
  140. void reshape(int w, int h)  
  141. {  
  142. global_w = w;  
  143. global_h = h;  
  144. points_clear();  
  145.   
  146. glViewport (0, 0, w, h);  
  147. glMatrixMode(GL_PROJECTION);  
  148. glLoadIdentity();  
  149.   
  150. glOrtho(0, w, 0, h, -1.0, 1.0);  
  151. glMatrixMode(GL_MODELVIEW);  
  152. glLoadIdentity();  
  153. }  
  154.   
  155. void mouse(int button, int state, int x, int y)   
  156. {  
  157. if ( button == GLUT_LEFT_BUTTON && state == GLUT_UP )  
  158. {  
  159. if( tri_state == 1 ) points_clear();  
  160. else   
  161. {  
  162. points_add_point(x,y);  
  163. //read_file();  
  164. points_draw();  
  165. }  
  166. }  
  167. if ( button == GLUT_RIGHT_BUTTON && state == GLUT_UP )   
  168. {  
  169. if( tri_state == 1 ) points_clear();  
  170. else points_triangulation();  
  171. }  
  172. }  
  173.   
  174. void keyboard(unsigned char key, int x, int y)  
  175. {  
  176. switch (key) {  
  177. case 27:  
  178. exit(0);  
  179. break;  
  180. }  
  181. }  
  182.   
  183. int main(int argc, char** argv)  
  184. {  
  185. glutInit(&argc, argv);  
  186. glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);  
  187. glutInitWindowSize (800, 600);   
  188. glutInitWindowPosition (100, 100);  
  189. glutCreateWindow (argv[0]);  
  190. init ();  
  191. glutDisplayFunc(display);   
  192. glutReshapeFunc(reshape);   
  193. glutMouseFunc(mouse);  
  194. glutKeyboardFunc(keyboard);  
  195. glutMainLoop();  
  196. return 0;  
  197. }  
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值