Ubuntu下改编了一个用CGAL计算输入点的三角剖分,并用OpenGL显示结果的C++程序。
该Demo可作为一个计算几何及绘图的框架。
代码如下:
//编译命令:g++ spatial_sort.cpp -lglut -lGL -lGLU -lCGAL -lCGAL_Core -lgmp #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Triangulation_euclidean_traits_xy_3.h> #include <CGAL/Delaunay_triangulation_2.h> #include <GL/glut.h> #include <iostream> #include <cmath> #include <time.h> using namespace std; typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Delaunay_triangulation_2<K> Delaunay; typedef Delaunay::Vertex_handle Vertex_handle; typedef K::Point_2 Point; std::vector<Point> vertices, mypts; int global_w, global_h; //绘制用户添加的点Pt(hx(), hy()) void points_draw() { glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); std::vector <Point>::iterator iter; glColor3f( 1.0, 1.0, 1.0 ); glPointSize(8); glBegin(GL_POINTS); for( iter = vertices.begin(); iter != vertices.end(); iter++ ) glVertex2i( iter->hx(), iter->hy() ); glEnd(); glPopMatrix(); glutSwapBuffers(); } //添加点 void points_add_point( int x, int y ) { vertices.push_back( Point( x, global_h-y ) ); } //清除点 void points_clear() { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glPopMatrix(); glutSwapBuffers(); vertices.clear(); } //计算点的三角剖分————Delaunary void points_triangulation() { //Delaunay数据结构,代表当前数据的一个且仅有一个的三角剖分,详情请参考CGAL_manual Delaunay dt; //将所有点加入dt dt.insert(vertices.begin(), vertices.end());//输入数据 //开始绘制 glPushMatrix(); Delaunay::Finite_faces_iterator fit;//遍历Delaunay的所有面(有限面),将每个面的边画出来 glColor3f( 0.0, 0.0, 1.0 ); for( fit = dt.finite_faces_begin(); fit != dt.finite_faces_end(); fit++) { glBegin(GL_LINE_LOOP); glVertex2i( fit->vertex(0)->point().hx(), fit->vertex(0)->point().hy() ); glVertex2i( fit->vertex(1)->point().hx(), fit->vertex(1)->point().hy() ); glVertex2i( fit->vertex(2)->point().hx(), fit->vertex(2)->point().hy() ); glEnd(); }//完成Delaunay三角剖分的绘制,Delaunay图 Delaunay::Edge_iterator eit;//遍历Delaunay的所有边,绘制Delaunay图的对偶图,即Voronoi图 glEnable( GL_LINE_STIPPLE );//使用点画模式,即使用虚线来绘制Voronoi图 glLineStipple( 1, 0x3333 ); glColor3f( 0.0, 1.0, 0.0 ); for( eit = dt.edges_begin(); eit != dt.edges_end(); eit ++) { CGAL::Object o = dt.dual(eit);//边eit在其对偶图中所对应的边 if (CGAL::object_cast<K::Segment_2>(&o)) //如果这条边是线段,则绘制线段 { glBegin(GL_LINES); glVertex2i( CGAL::object_cast<K::Segment_2>(&o)->source().hx(), CGAL::object_cast<K::Segment_2>(&o)->source().hy() ); glVertex2i( CGAL::object_cast<K::Segment_2>(&o)->target().hx(), CGAL::object_cast<K::Segment_2>(&o)->target().hy() ); glEnd(); } else if (CGAL::object_cast<K::Ray_2>(&o))//如果这条边是射线,则绘制射线 { glBegin(GL_LINES); glVertex2i( CGAL::object_cast<K::Ray_2>(&o)->source().hx(), CGAL::object_cast<K::Ray_2>(&o)->source().hy() ); glVertex2i( CGAL::object_cast<K::Ray_2>(&o)->point(1).hx(), CGAL::object_cast<K::Ray_2>(&o)->point(1).hy() ); glEnd(); } } glDisable( GL_LINE_STIPPLE );//关闭点画模式 glPopMatrix(); glutSwapBuffers(); } void display(void) { //清除屏幕内容 /* glClear(GL_COLOR_BUFFER_BIT); points_triangulation(); points_draw(); //刷新结果 glFlush() ; glutSwapBuffers(); */ } //初始化背景与shade模式 void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } //调整窗口大小 void reshape(int w, int h) { global_w = w; global_h = h; //设置视口属性 glViewport (0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //设置坐标系 glOrtho(0, w, 0, h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //重新绘制点 points_draw(); } //鼠标事件处理 void mouse(int button, int state, int x, int y) { //如果按下鼠标左键,则添加点 if ( button == GLUT_LEFT_BUTTON ) { points_add_point(x,y); points_draw(); } //若按下右键,则绘制三角剖分结果---计算 if ( button == GLUT_RIGHT_BUTTON ) points_triangulation(); } //键盘事件处理 void keyboard(unsigned char key, int x, int y) { //按下ESC键,则程序退出 switch (key) { case 'c': points_clear(); break; case 'r': points_draw(); break; case ' ': points_triangulation(); break; case 's': break; //save_as_png('test.png'); case 27 : case 'x': exit(0); break; } } //主函数 int main(int argc, char** argv) { //初始化随机种子 srand(time(NULL)); //glutInit... glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (800, 600); //设置窗口宽度和高度 glutInitWindowPosition (0, 0); //初始化窗口位置 //窗口 glutCreateWindow (argv[0]); //设置背景色及阴影模式 init(); //绘画函数 glutDisplayFunc(display); //改变窗口大小时的绘制函数 glutReshapeFunc(reshape); //鼠标事件处理函数 glutMouseFunc(mouse); //键盘事件处理函数 glutKeyboardFunc(keyboard); //无限主循环 glutMainLoop(); return 0; }
原文:http://blog.csdn.net/miscclp/article/details/44246485