首页 > 其他 > 详细

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

时间:2015-03-13 23:49:40      阅读:2041      评论:0      收藏:0      [点我收藏+]

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;  
}


技术分享

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

原文:http://blog.csdn.net/miscclp/article/details/44246485

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!