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,结果如下:

posted @ 2022-09-30 12:23  小帆敲代码  阅读(65)  评论(0编辑  收藏  举报