球体的细分逼近程序 Posted on 2020-03-18 | In 图形图像处理 | 864 | 4 分钟 用C++实现四面体递归逼近球体 球体的细分逼近程序 通过递归细分四面体生成球体,三种显示模式:线性框、均匀着色,插值着色 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138/* 该程序在init()函数中还定义了材质和光源 *//* mode 0 = 线性框, mode 1 = 均与着色,mode 3 = 插值着色 */#include <stdlib.h>#include<math.h>#include <GL/glut.h>typedef float point[4];/* 初始化四面体 */point v[]={{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.33333}, {-0.816497, -0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}};GLfloat theta[] = {0.0,0.0,0.0};int n;int mode;void triangle( point a, point b, point c)/*利用GL_LINR_LOOP模式显示一个三角形的线性图,定义一个法向量用于均匀着色,定义三个法向量用于插值着色*/{ if (mode==0) glBegin(GL_LINE_LOOP); else glBegin(GL_POLYGON); if(mode==1) glNormal3fv(a); if(mode==2) glNormal3fv(a); glVertex3fv(a); if(mode==2) glNormal3fv(b); glVertex3fv(b); if(mode==2) glNormal3fv(c); glVertex3fv(c); glEnd();}void normal(point p){/* 矢量归一化 */double sqrt(double d);float d = 0.0;int i;for (i = 0; i < 3; i++) d += p[i] * p[i];d = sqrt(d);if (d > 0.0) for (i = 0; i < 3; i++) p[i] /= d;}void divide_triangle(point a, point b, point c, int m){/* 基于顶点数目细分三角形,应用右手规则生成对象的外向表面 */ point v1, v2, v3; int j; if(m>0) { for(j=0; j<3; j++) v1[j]=a[j]+b[j]; normal(v1); for(j=0; j<3; j++) v2[j]=a[j]+c[j]; normal(v2); for(j=0; j<3; j++) v3[j]=b[j]+c[j]; normal(v3); divide_triangle(a, v1, v2, m-1); divide_triangle(c, v2, v3, m-1); divide_triangle(b, v3, v1, m-1); divide_triangle(v1, v3, v2, m-1); } else triangle(a,b,c); /* 递归结束时绘制三角形 */}void tetrahedron(int m){/* 对四面体的表面应用三角细分 */ divide_triangle(v[0], v[1], v[2], m); divide_triangle(v[3], v[2], v[1], m); divide_triangle(v[0], v[3], v[1], m); divide_triangle(v[0], v[2], v[3], m);}void display(){/* 逐一显示这三种模式下的四面体 */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); mode=0; tetrahedron(n); mode=1; glTranslatef(-2.0, 0.0, 0.0); tetrahedron(n); mode=2; glTranslatef(4.0, 0.0, 0.0); tetrahedron(n); glFlush();}void myReshape(int w, int h){ glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-4.0, 4.0, -4.0 * (GLfloat) h / (GLfloat) w, 4.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-4.0 * (GLfloat) w / (GLfloat) h, 4.0 * (GLfloat) w / (GLfloat) h, -4.0, 4.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); display();}void myinit(){ GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_ambient[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_shininess={100.0}; GLfloat light_ambient[]={0.0, 0.0, 0.0, 1.0}; GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0};/* 为光源0分别设置环境光、漫反射光和镜面反射光的参数 */ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);/* 为所有三角形正面定义材质属性 */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); glShadeModel(GL_SMOOTH); /* 开启平滑着色 */ glEnable(GL_LIGHTING); /* 开启光照 */ glEnable(GL_LIGHT0); /* 开启光源0 */ glEnable(GL_DEPTH_TEST); /* 开启z-buffer */ glClearColor (1.0, 1.0, 1.0, 1.0); glColor3f (0.0, 0.0, 0.0);}main(int argc, char **argv){ n=4;//n=1,2,3,4,5,6…… //n=atoi(argv[1]);//直接运行会出错,具体参照BookCode的此处源码处理方案 glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("sphere"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMainLoop();} 结果 -------------------本文结束 感谢您的阅读------------------- Donate WeChat Pay Alipay