Advertisement
Chris_M_Thomasson

3d von Koch by Chris M. Thomasson

Jan 5th, 2016
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.49 KB | None | 0 0
  1. I start with the following vertexs for a triangular regular pyramid, in the unit cube.
  2.  
  3. glm::vec3 t[] = {
  4. glm::vec3(-1.0, -1.0, 1.0),
  5. glm::vec3(1.0, -1.0, 1.0),
  6. glm::vec3(0.0, -1.0, -1.0),
  7. glm::vec3(0.0, 1.0, 0.0)
  8. };
  9.  
  10.  
  11. I then index into these to create four triangles.
  12.  
  13. One for each side.
  14.  
  15. g.push_points3(g.m_vindex, 0, 1, 3);
  16. g.push_points3(g.m_vindex, 1, 2, 3);
  17. g.push_points3(g.m_vindex, 2, 0, 3);
  18. g.push_points3(g.m_vindex, 0, 1, 2);
  19.  
  20. This creates a tetrahedron. Keep in mind that this scales to any triangle, so a cube would work with two triangles per face.
  21.  
  22.  
  23. I then iterate each triangle in the tetrahedron:
  24.  
  25. g.iterate_triangle(0, imax, length, t[0], t[1], t[3]);
  26. g.iterate_triangle(0, imax, length, t[1], t[2], t[3]);
  27. g.iterate_triangle(0, imax, length, t[2], t[0], t[3]);
  28. g.iterate_triangle(0, imax, length, t[1], t[0], t[2]);
  29.  
  30.  
  31. The code for the recursive function (iterate_triangle) is:
  32.  
  33. _____________________________________
  34. glm::vec3 get_scale_point(glm::vec3 p0, glm::vec3 p1, double scale)
  35. {
  36. glm::vec3 diff = p1 - p0;
  37.  
  38. return glm::vec3(
  39. p0.x + diff.x * scale,
  40. p0.y + diff.y * scale,
  41. p0.z + diff.z * scale
  42. );
  43. }
  44.  
  45. glm::vec3
  46. get_tip_from_triangle(
  47. glm::vec3 p0, // bottom left
  48. glm::vec3 p1, // bottom right
  49. glm::vec3 p2, // top,
  50. glm::vec3 topb, // bottom of the new top,
  51. double length
  52. ){
  53. glm::vec3 tcross = glm::cross(p1 - p0, p2 - p0);
  54.  
  55. double tlen = glm::length(tcross);
  56. double s = length / tlen;
  57.  
  58. glm::vec3 ret(
  59. topb.x + tcross.x * s,
  60. topb.y + tcross.y * s,
  61. topb.z + tcross.z * s
  62. );
  63.  
  64. double d = glm::distance(ret, topb);
  65.  
  66. std::printf("length: %lf - %lf\r\n", length, d);
  67.  
  68. return ret;
  69. }
  70.  
  71.  
  72. /* iterate a triangle */
  73. void iterate_triangle(
  74. unsigned int irecur,
  75. unsigned int irecur_max,
  76. double length,
  77. glm::vec3 p0, // bottom left
  78. glm::vec3 p1, // top bottom right
  79. glm::vec3 p2 // top
  80. ){
  81.  
  82. if (irecur >= irecur_max) return;
  83.  
  84. unsigned int vbase = (m_verts.size() / 3);
  85.  
  86.  
  87. glm::vec3 bmid = get_scale_point(p0, p1, 0.5);
  88. glm::vec3 topb = get_scale_point(bmid, p2, 0.5);
  89.  
  90. double scale = 1.0 / 2.0;
  91. glm::vec3 top_left = get_scale_point(p0, p2, scale);
  92. glm::vec3 top_right = get_scale_point(p1, p2, scale);
  93. glm::vec3 bottom_mid = bmid;
  94. glm::vec3 ttop = get_tip_from_triangle(p0, p1, p2, topb, length);
  95.  
  96.  
  97. push_points3(m_verts, top_left);
  98. push_points4(m_colors, glm::vec4(1.0, 0.0, 0.0, 1.0));
  99.  
  100. push_points3(m_verts, top_right);
  101. push_points4(m_colors, glm::vec4(0.0, 1.0, 0.0, 1.0));
  102.  
  103. push_points3(m_verts, bottom_mid);
  104. push_points4(m_colors, glm::vec4(0.0, 0.0, 1.0, 1.0));
  105.  
  106. push_points3(m_verts, ttop);
  107. push_points4(m_colors, glm::vec4(1.0, 1.0, 0.0, 1.0));
  108.  
  109. push_points3(m_vindex, vbase + 0, vbase + 1, vbase + 3);
  110. push_points3(m_vindex, vbase + 0, vbase + 2, vbase + 3);
  111. push_points3(m_vindex, vbase + 2, vbase + 1, vbase + 3);
  112.  
  113.  
  114.  
  115. double blength = length * 0.33333;
  116. double tlength = length * 0.3333333;
  117.  
  118. iterate_triangle(irecur + 1, irecur_max, blength, top_right, top_left, ttop);
  119. iterate_triangle(irecur + 1, irecur_max, blength, top_left, bottom_mid, ttop);
  120. iterate_triangle(irecur + 1, irecur_max, blength, bottom_mid, top_right, ttop);
  121.  
  122. iterate_triangle(irecur + 1, irecur_max, tlength, top_left, top_right, p2);
  123. iterate_triangle(irecur + 1, irecur_max, tlength, p0, bmid, top_left);
  124. iterate_triangle(irecur + 1, irecur_max, tlength, bmid, p1, top_right);
  125. }
  126. _____________________________________
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement