球体的细分逼近程序

用C++实现四面体递归逼近球体

球体的细分逼近程序

通过递归细分四面体生成球体,三种显示模式:线性框、均匀着色,插值着色

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* 该程序在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();
}

结果

-------------------本文结束 感谢您的阅读-------------------
0%