Opengl绘制计算几何库CGAL三角剖分结果的Demo

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();  }   //计算点的三角剖分————Delaunaryvoid 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;  }

当你能梦的时候就不要放弃梦

Opengl绘制计算几何库CGAL三角剖分结果的Demo

相关文章:

你感兴趣的文章:

标签云: