Sierpinski图形是一类有趣的图形,本文结合交互式图形学教材,讲解Sierpinski镂垫图形生成,作为入门图形学编程的第一课。为了简便,本文就2D来进行讨论。实验环境见01
算法
主要是根据随机性生成一系列的点,这些点在屏幕上显示,发现无序中尽显有序!算法流程如下:
1 在三角形内随机选择一个初始点p(x, y)
2 随机选择三角形顶点之一
3 计算p和随机选择顶点之间的中点q
4 将q对应位置用相应标记在图形中显示出来
5 用这个中点q代替原来的p
6 转到步骤2,直到取得一定数量的点
代码
实验中,初始点p选择三角形的一条中位线的中点,总共生成5000个顶点
1 #include <glut.h>
2 #include <stdlib.h>
3 #include <vector>
4 using namespace std;
5
6 class Point2d {
7 public:
8 GLfloat x = 0.0f;
9 GLfloat y = 0.0f;
10 Point2d(const GLfloat &a, const GLfloat &b) : x(a), y(b) {}
11 Point2d() {}
12 };
13
14 Point2d triVer[3]; // 初始三角形顶点
15
16 // 计算两点连线的中点
17 Point2d halfScale(const Point2d &a, const Point2d &b) {
18 Point2d res;
19 res.x = (a.x + b.x) / 2.0;
20 res.y = (a.y + b.y) / 2.0;
21 return res;
22 }
23
24 void SierpinskiDisp() {
25
26 // 设置初始三角形顶点
27 triVer[0] = Point2d(-0.8f, -0.8f);
28 triVer[1] = Point2d(0.0f, 0.8f);
29 triVer[2] = Point2d(0.8f, -0.8f);
30
31 vector<Point2d> points(5000);
32
33 // 取三角形一条中位线的中点做为初始三角形内的点
34 Point2d u, v, p;
35 u = halfScale(triVer[0], triVer[1]);
36 v = halfScale(triVer[0], triVer[2]);
37 p = halfScale(u, v);
38 points[0].x = p.x;
39 points[0].y = p.y;
40
41 for (int i = 1; i < 5000; i++) {
42 int j = rand() % 3;
43 p = halfScale(points[i - 1], triVer[j]);
44 points[i] = p;
45 }
46 glClearColor(0.5, 0.5, 0.5, 1.0);
47 glClear(GL_COLOR_BUFFER_BIT);
48
49 // 画三角形顶点
50 glColor3f(1.0f, 0.0f, 0.0f);
51 glPointSize(6.0f);
52 glBegin(GL_POINTS);
53 for (int i = 0; i < 3; i++) {
54 glVertex2f(triVer[i].x, triVer[i].y);
55 }
56 glEnd();
57
58 // 画随机生成的5000个点
59 glColor3f(1.0f, 1.0f, 0.0f);
60 glPointSize(3.0f);
61 glBegin(GL_POINTS);
62 for (int i = 0; i < 5000; i++) {
63 glVertex2f(points[i].x, points[i].y);
64 }
65 glEnd();
66 glFlush();
67 }
68
69 int main(int argc, char *argv[]) {
70 glutInit(&argc, argv);
71 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
72 glutInitWindowPosition(100, 100);
73 glutInitWindowSize(600, 600);
74 glutCreateWindow("Sierpinski镂垫");
75 glutDisplayFunc(&SierpinskiDisp);
76 glutMainLoop();
77 }
结果