Sierpinski 镂垫程序

用C++实现三个 Sierpinski 镂垫程序

Sierpinski镂垫是一个非常有趣的图案,有着悠久的历史, 在分形几何中等领域里引起了人们极大地兴趣, 是用递归和随机方式定义的几何形状。

生成算法如下:

  1. 在三角形内部随机选取一个点作为初始点;
  2. 在三角形的3个顶点中随机选取一个,求出该顶点与初始点连线的中点,画出该中点;
  3. 将第二步中的中点作为初始点,循环第二步;

1 二维Sierpinski镂垫

代码

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
/*使用随机选择的顶点和中点绘制二维Sierpinski镂垫*/
#include <windows.h>
#include <GL/glut.h>

void myinit()
{
glClearColor(1.0,1.0,1.0,1.0);/*白色背景*/
glColor3f(1.0,0.0,0.0);/*红色*/

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);/*50×50相机坐标窗口与原点左下角*/
glMatrixMode(GL_MODELVIEW);

}

void display()
{
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}};

int j,k;
int rand();/*产生随机数*/
GLfloat p[2]={7.5,5.0};/*在三角形内任意初始点*/
glClear(GL_COLOR_BUFFER_BIT);/*清理窗口*/

glBegin(GL_POINTS);/*产生5000个新点*/

for(k=0;k<5000;k++)
{
j=rand()%3;/*随机选择一个顶点*/
/*计算点位于选定顶点和旧点之间*/
p[0]=(p[0]+vertices[j][0])/2.0;
p[1]=(p[1]+vertices[j][1])/2.0;
/*画新点*/
glVertex2fv(p);
}
glEnd();
glFlush();/*清除缓冲帧*/
}

int main(int argc,char *argv[])
{
glutInit(&argc,argv);/*标准的GLUT初始化*/
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);/*默认设置*/
glutInitWindowSize(500,500);/*500×500像素窗口*/
glutInitWindowPosition(0,0);/*将窗口放在左下角*/
glutCreateWindow("Sierpinski Gasket");/*窗口名*/
glutDisplayFunc(display);/*窗口打开时调用的显示回调*/
myinit();/*设置属性*/
glutMainLoop();/*进入事件循环*/
}

结果

2 生成 Sierpinski 镂垫的递归程序

代码

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
/* 通过细分三角形的方法生成Sierpinski镂垫 */
/* 通过命令行输入递归的次数 */
#include <GL/glut.h>
#include<stdlib.h>
/* 初始的三角形 */
GLfloat v[3][2]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};
int n;
void triangle( GLfloat *a, GLfloat *b, GLfloat *c)
/* 定义某个三角形 */
{
glVertex2fv(a);
glVertex2fv(b);
glVertex2fv(c);
}
void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c, int m)
{
/* 基于某个顶点的数量对三角形进行细分处理 */
GLfloat v0[2], v1[2], v2[2];
int j;
if(m>0)
{
for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2;
for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2;
for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2;
divide_triangle(a, v0, v1, m-1);
divide_triangle(c, v1, v2, m-1);
divide_triangle(b, v2, v0, m-1);
}
else triangle(a,b,c); /* 递归结束时绘制三角形 */
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
divide_triangle(v[0], v[1], v[2], n);
glEnd();
glFlush();
}
void myinit()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-2.0, 2.0, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0,0.0,0.0);
}
main(int argc, char **argv)
{
n=3; /* 或者在此输入三角形细分的步数 */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}

结果

3 三维 Sierpinski 镂垫的递归程序

代码

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
/* 通过递归细分四面体方法生成Sierpinski镂垫 */
/* 通过命令行递归的次数 */
#include <stdlib.h>
#include <GL/glut.h>
/* 初始的四面体 */
GLfloat v[4][3]={{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 colors[4][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},
{0.0,0.0,1.0},{0.0,0.0,0.0}};
int n;
void triangle( GLfloat *va, GLfloat *vb, GLfloat *vc)
{
glVertex3fv(va);
glVertex3fv(vb);
glVertex3fv(vc);
}
void tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d)
{
glColor3fv(colors[0]);
triangle(a,b,c);
glColor3fv(colors[1]);
triangle(a,c,d);
glColor3fv(colors[2]);
triangle(a,d,b);
glColor3fv(colors[3]);
triangle(b,d,c);
}
void divide_tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m)
{
GLfloat mid[6][3];
int j;
if(m>0)
{
/* 计算六个中点 */
for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2;
for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2;
for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2;
for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2;
for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2;
for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2;
/* 通过细分生成四个四面体 */
divide_tetra(a,mid[0],mid[1],mid[2], m-1);
divide_tetra(mid[0],b,mid[3],mid[5], m-1);
divide_tetra(mid[1],mid[3],c,mid[4], m-1);
divide_tetra(mid[2],mid[4],d,mid[5], m-1);
}
else tetra(a,b,c,d); /* 递归结束时绘制四面体 */
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
divide_tetra(v[0],v[1],v[2],v[3],n);
glEnd();
glFlush();
}
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
else
glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
main(int argc, char **argv)
{
n=atoi(argv[1]); /* 或者在此处输入四面体细分的步数 */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("3D Gasket");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glEnable(GL_DEPTH_TEST);
glClearColor (1.0, 1.0, 1.0, 1.0);
glutMainLoop();
}

结果

-------------------本文结束 感谢您的阅读-------------------
0%
  1. 1 Beautiful In White (Demo) Westlife
  2. 2 My Love Westlife
  3. 3 Five hundred miles The Journeymen
  4. 4 Wait For You Elliott Yamin
  5. 5 Here With You Asher Monroe
  6. 6 Refrain Anan Ryoko
  7. 7 下完这场雨 后弦
  8. 8 宠爱 王俊凯
  9. 9 城南花已开 三亩地
  10. 10 词不达意 (Live) 林忆莲
  11. 11 我在诛仙逍遥涧 王俊凯
  12. 12 李白 李荣浩
  13. 13 Perfect Boyce Avenue
  14. 14 遇见 孙燕姿
  15. 15 Lucky Lenka
  16. 16 明天你好 牛奶咖啡
  17. 17 我的梦 (Live) 张靓颖/马臻
  18. 18 勇气 梁静茹
  19. 19 曾经的你 许巍
  20. 20 她说 林俊杰
  21. 21 世间美好与你环环相扣 柏松
  22. 22 All Falls Down Alan Walker
  23. 23 Faded Alan Walker
Beautiful In White (Demo) - Westlife
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.
看板娘