Graphis IFS(Iteration Function System)迭代函数系统
任务描述
使用变换(R T)描述IFS
点IFS
代码:
//操纵点
void sierpinski_triangle_point(Vec3f &v, ArgParser* args) {
for (int j = 0; j < args->iters; j++) {
double p = args->mtrand.rand();
//轮盘 找到做哪个变换
Matrix m = matrixs[0];
for (int i = 0; i < num_transforms - 1; i++)
{
if (p > probabilities[i] && p <= probabilities[i + 1]) {
m = matrixs[i + 1];
break;
}
}
v = m * v;
}
}
void IFS::setupPoints() {
HandleGLError("in setup points");
// allocate space for the data
VBOPoint* points = new VBOPoint[(args->points)];
// generate a block of random data
for (int i = 0; i < args->points; i++) {
double x = args->mtrand.rand();//生成0,1的点
double y = args->mtrand.rand();
double z = args->mtrand.rand();
Vec3f v(x, y, z);
// ASSIGNMENT: manipulate point
sierpinski_triangle_point(v, args);//三角形
points[i] = VBOPoint(v);
}
// create a pointer for the VBO
glGenBuffers(1, &points_VBO);
// copy the data to the VBO
glBindBuffer(GL_ARRAY_BUFFER,points_VBO);
glBufferData(GL_ARRAY_BUFFER,
sizeof(VBOPoint) * args->points,
points,
GL_STATIC_DRAW);
delete [] points;
HandleGLError("leaving setup points");
}
Sierpinski三角形
- 变换如下,sierpinski_triangle.txt :
3 # 这里我理解是每次变成几倍(变成原来的多少分之一)
0.33
0.500000 0.000000 0.000000 0.000000
0.000000 0.500000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
0.33
0.500000 0.000000 0.000000 0.500000
0.000000 0.500000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
0.34
0.500000 0.000000 0.000000 0.000000
0.000000 0.500000 0.000000 0.500000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
- 使用
-input sierpinski_triangle.txt -points 10000 -iters 30 -size 200
运行结果:
giant_x
- 变换,giant_x.txt:
5
0.2
0.33 0.00 0.00 0.00
0.00 0.33 0.00 0.00
0.00 0.00 0.33 0.00
0.00 0.00 0.00 1.00
0.2
0.33 0.00 0.00 0.66
0.00 0.33 0.00 0.00
0.00 0.00 0.33 0.66
0.00 0.00 0.00 1.00
0.2
0.33 0.00 0.00 0.33
0.00 0.33 0.00 0.33
0.00 0.00 0.33 0.33
0.00 0.00 0.00 1.00
0.2
0.33 0.00 0.00 0.00
0.00 0.33 0.00 0.66
0.00 0.00 0.33 0.66
0.00 0.00 0.00 1.00
0.2
0.33 0.00 0.00 0.66
0.00 0.33 0.00 0.66
0.00 0.00 0.33 0.00
0.00 0.00 0.00 1.00
- 运行
-input giant_x.txt -points 10000 -iters 30 -size 200
结果如下:
fern.txt
- 变换fern.txt:
4
0.03
0.000001 0.000000 0.0 0.500000
0.000000 0.205000 0.0 0.000000
0.000000 0.000000 0.5 0.25
0.000000 0.000000 0.0 1.000000
0.71
0.817377 0.065530 0.0 0.091311
-0.065530 0.817377 0.0 0.232765
0.000000 0.000000 0.5 0.25
0.000000 0.000000 0.0 1.000000
0.13
0.108707 -0.372816 0.0 0.445646
0.279612 0.144943 0.0 -0.059806
0.000000 0.000000 0.5 0.25
0.000000 0.000000 0.0 1.000000
0.13
-0.080250 0.385423 0.0 0.540125
0.289067 0.107000 0.0 -0.004534
0.000000 0.000000 -0.5 0.75
0.000000 0.000000 0.0 1.000000
- 运行
-input fern.txt -points 10000 -iters 30 -size 200
结果如下:
dragon
- 变换dragon.txt:
2
0.5
0.5 0.5 0.0 -0.25
-0.5 0.5 0.0 0.25
0.0 0.0 0.7 -0.20
0.0 0.0 0.0 1.00
0.5
-0.5 0.5 0.0 0.75
-0.5 -0.5 0.0 0.75
0.0 0.0 0.7 0.20
0.0 0.0 0.0 1.00
- 运行
-input dragon.txt -points 10000 -iters 30 -size 200
结果如下:
Cube IFS
代码
int face_size = 6;
int cube_vert_size = face_size * 4;
//转换一次cube
VBOVertex* translateCube(VBOVertex* cube_verts_origin,int size)
{
VBOVertex* cube_verts_new = new VBOVertex[size*20];
int cube_size = size / 24;
for (int i = 0; i < cube_size; i++) {
for (int it = 0; it < 20; it++) {
Matrix m = matrixs[it];
for (int j = 0; j < 24; j++) {
//cube_verts_new[i*480+it*24+j] = m * cube_verts_origin[i * 24 + j];
Vec3f v_origin(cube_verts_origin[i * 24 + j].x,
cube_verts_origin[i * 24 + j].y,
cube_verts_origin[i * 24 + j].z);
Vec3f v_new = m * v_origin;
cube_verts_new[i * 480 + it * 24 + j].x = v_new.x();
cube_verts_new[i * 480 + it * 24 + j].y = v_new.y();
cube_verts_new[i * 480 + it * 24 + j].z = v_new.z();
cube_verts_new[i * 480 + it * 24 + j].nx = cube_verts_origin[i * 24 + j].nx;
cube_verts_new[i * 480 + it * 24 + j].ny = cube_verts_origin[i * 24 + j].ny;
cube_verts_new[i * 480 + it * 24 + j].nz = cube_verts_origin[i * 24 + j].nz;
cube_verts_new[i * 480 + it * 24 + j].cx = cube_verts_origin[i * 24 + j].cx;
cube_verts_new[i * 480 + it * 24 + j].cy = cube_verts_origin[i * 24 + j].cy;
cube_verts_new[i * 480 + it * 24 + j].cz = cube_verts_origin[i * 24 + j].cz;
}
}
}
return cube_verts_new;
}
void IFS::setupCube() {
HandleGLError("in setup cube");
VBOVertex* cube_verts = new VBOVertex[cube_vert_size];
VBOQuad* cube_face_indices = new VBOQuad[face_size];
// initialize vertex data
// back face, cyan
cube_verts[0] = VBOVertex(Vec3f(0, 0, 0), Vec3f(0, 0, -1), Vec3f(0, 1, 1));
cube_verts[1] = VBOVertex(Vec3f(0, 1, 0), Vec3f(0, 0, -1), Vec3f(0, 1, 1));
cube_verts[2] = VBOVertex(Vec3f(1, 1, 0), Vec3f(0, 0, -1), Vec3f(0, 1, 1));
cube_verts[3] = VBOVertex(Vec3f(1, 0, 0), Vec3f(0, 0, -1), Vec3f(0, 1, 1));
//position normal color
// front face, red
cube_verts[4] = VBOVertex(Vec3f(0, 0, 1), Vec3f(0, 0, 1), Vec3f(1, 0, 0));
cube_verts[5] = VBOVertex(Vec3f(0, 1, 1), Vec3f(0, 0, 1), Vec3f(1, 0, 0));
cube_verts[6] = VBOVertex(Vec3f(1, 1, 1), Vec3f(0, 0, 1), Vec3f(1, 0, 0));
cube_verts[7] = VBOVertex(Vec3f(1, 0, 1), Vec3f(0, 0, 1), Vec3f(1, 0, 0));
// bottom face, purple
cube_verts[8] = VBOVertex(Vec3f(0, 0, 0), Vec3f(0, -1, 0), Vec3f(1, 0, 1));
cube_verts[9] = VBOVertex(Vec3f(0, 0, 1), Vec3f(0, -1, 0), Vec3f(1, 0, 1));
cube_verts[10] = VBOVertex(Vec3f(1, 0, 1), Vec3f(0, -1, 0), Vec3f(1, 0, 1));
cube_verts[11] = VBOVertex(Vec3f(1, 0, 0), Vec3f(0, -1, 0), Vec3f(1, 0, 1));
// top face, green
cube_verts[12] = VBOVertex(Vec3f(0, 1, 0), Vec3f(0, 1, 0), Vec3f(0, 1, 0));
cube_verts[13] = VBOVertex(Vec3f(0, 1, 1), Vec3f(0, 1, 0), Vec3f(0, 1, 0));
cube_verts[14] = VBOVertex(Vec3f(1, 1, 1), Vec3f(0, 1, 0), Vec3f(0, 1, 0));
cube_verts[15] = VBOVertex(Vec3f(1, 1, 0), Vec3f(0, 1, 0), Vec3f(0, 1, 0));
// left face, yellow
cube_verts[16] = VBOVertex(Vec3f(0, 0, 0), Vec3f(-1, 0, 0), Vec3f(1, 1, 0));
cube_verts[17] = VBOVertex(Vec3f(0, 0, 1), Vec3f(-1, 0, 0), Vec3f(1, 1, 0));
cube_verts[18] = VBOVertex(Vec3f(0, 1, 1), Vec3f(-1, 0, 0), Vec3f(1, 1, 0));
cube_verts[19] = VBOVertex(Vec3f(0, 1, 0), Vec3f(-1, 0, 0), Vec3f(1, 1, 0));
// right face, blue
cube_verts[20] = VBOVertex(Vec3f(1, 0, 0), Vec3f(1, 0, 0), Vec3f(0, 0, 1));
cube_verts[21] = VBOVertex(Vec3f(1, 0, 1), Vec3f(1, 0, 0), Vec3f(0, 0, 1));
cube_verts[22] = VBOVertex(Vec3f(1, 1, 1), Vec3f(1, 0, 0), Vec3f(0, 0, 1));
cube_verts[23] = VBOVertex(Vec3f(1, 1, 0), Vec3f(1, 0, 0), Vec3f(0, 0, 1));
for (int i = 0; i < args->iters; i++)
{
//变换Cube
cube_verts = translateCube(cube_verts, cube_vert_size);
cube_vert_size *= 20;
//面个数变化
face_size *= 20;
}
//操纵面
cube_face_indices = new VBOQuad[face_size];
for (int j = 0; j < face_size / 6; j++)
{
cube_face_indices[0 + j * 6] = VBOQuad(0 + j * 24, 1 + j * 24, 2 + j * 24, 3 + j * 24);
cube_face_indices[1 + j * 6] = VBOQuad(4 + j * 24, 7 + j * 24, 6 + j * 24, 5 + j * 24);
cube_face_indices[2 + j * 6] = VBOQuad(8 + j * 24, 11 + j * 24, 10 + j * 24, 9 + j * 24);
cube_face_indices[3 + j * 6] = VBOQuad(12 + j * 24, 13 + j * 24, 14 + j * 24, 15 + j * 24);
cube_face_indices[4 + j * 6] = VBOQuad(16 + j * 24, 17 + j * 24, 18 + j * 24, 19 + j * 24);
cube_face_indices[5 + j * 6] = VBOQuad(20 + j * 24, 23 + j * 24, 22 + j * 24, 21 + j * 24);
}
// create a pointer for the vertex & index VBOs
glGenBuffers(1, &cube_verts_VBO);
glGenBuffers(1, &cube_face_indices_VBO);
// copy the data to each VBO
glBindBuffer(GL_ARRAY_BUFFER,cube_verts_VBO);
glBufferData(GL_ARRAY_BUFFER,
//sizeof(VBOVertex) * NUM_CUBE_VERTS,
sizeof(VBOVertex) * cube_vert_size,
cube_verts,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,cube_face_indices_VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
//sizeof(unsigned int) * NUM_CUBE_QUADS * 4,
sizeof(unsigned int) * face_size * 4,
cube_face_indices, GL_STATIC_DRAW);
HandleGLError("leaving setup cube");
delete [] cube_verts;
delete [] cube_face_indices;
}
变换矩阵cube.txt:
20
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.333333
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.333333
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.333333
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.333333
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.000000
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.333333
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.333333
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.333333
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.333333
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.333333
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.000000
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.333333
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.333333
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.000000
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.333333
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
0.05
0.333333 0.000000 0.000000 0.666666
0.000000 0.333333 0.000000 0.666666
0.000000 0.000000 0.333333 0.666666
0.000000 0.000000 0.000000 1.000000
运行结果
运行-input cube.txt -points 10000 -iters 3 -size 200 -cubes
,结果如下: