Advertisement
Chris_M_Thomasson

von Koch (kind of fixed for now)

Jan 17th, 2015
468
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.80 KB | None | 0 0
  1. #include <glut.h>
  2. #include <math.h>
  3.  
  4.  
  5.  
  6. struct vector3d
  7. {
  8. GLfloat x;
  9. GLfloat y;
  10. GLfloat z;
  11. };
  12.  
  13. #define VECTOR3D_SINIT_EX(mp_x, mp_y, mp_z) { mp_x, mp_y, mp_z }
  14. #define VECTOR3D_SINIT() VECTOR3D_SINIT_EX(0.0, 0.0, 0.0)
  15.  
  16.  
  17. struct color
  18. {
  19. GLfloat r;
  20. GLfloat g;
  21. GLfloat b;
  22. };
  23.  
  24.  
  25.  
  26.  
  27. static char title[] = "3D von Koch Curve";
  28.  
  29.  
  30. static GLfloat anime_angle_koch = 1.0;
  31. static int anime_angle_koch_timer = 15.0;
  32.  
  33.  
  34.  
  35.  
  36.  
  37. void
  38. timer_redraw_scene(
  39. int value
  40. ){
  41. glutPostRedisplay();
  42. glutTimerFunc(anime_angle_koch_timer, timer_redraw_scene, 0);
  43. }
  44.  
  45.  
  46.  
  47. struct vector3d
  48. vector_subtract(
  49. struct vector3d p0,
  50. struct vector3d p1
  51. ){
  52. struct vector3d np;
  53.  
  54. np.x = p0.x - p1.x;
  55. np.y = p0.y - p1.y;
  56. np.z = p0.z - p1.z;
  57.  
  58. return np;
  59. }
  60.  
  61.  
  62. double
  63. vector_length(
  64. struct vector3d p0,
  65. struct vector3d p1
  66. ){
  67. struct vector3d dif = vector_subtract(p0, p1);
  68. return sqrt(dif.x * dif.x + dif.y * dif.y + dif.z * dif.z);
  69. }
  70.  
  71.  
  72. struct vector3d
  73. vector_normal(
  74. struct vector3d p
  75. ){
  76. struct vector3d np = VECTOR3D_SINIT();
  77.  
  78. double length = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
  79.  
  80. if (length != 0.0)
  81. {
  82. np.x = p.x / length;
  83. np.y = p.y / length;
  84. np.z = p.z / length;
  85. }
  86.  
  87. return np;
  88. }
  89.  
  90.  
  91. struct vector3d
  92. vector_cross(
  93. struct vector3d p0,
  94. struct vector3d p1
  95. ){
  96. struct vector3d np;
  97.  
  98. np.x = p0.y * p1.z - p0.z * p1.y;
  99. np.y = p0.z * p1.x - p0.x * p1.z;
  100. np.z = p0.x * p1.y - p0.y * p1.x;
  101.  
  102. return np;
  103. }
  104.  
  105.  
  106. struct vector3d
  107. vector_triangle_cross(
  108. struct vector3d p0,
  109. struct vector3d p1,
  110. struct vector3d p2
  111. ){
  112. struct vector3d e0 = vector_subtract(p0, p1);
  113. struct vector3d e1 = vector_subtract(p1, p2);
  114. struct vector3d np = vector_cross(e0, e1);
  115.  
  116. return np;
  117. }
  118.  
  119.  
  120.  
  121.  
  122.  
  123. void
  124. init_gl()
  125. {
  126. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  127. glClearDepth(1.0f);
  128. glEnable(GL_DEPTH_TEST);
  129. glDepthFunc(GL_LEQUAL);
  130. glShadeModel(GL_FLAT);
  131. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  132. }
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140. void
  141. iterate_triangle(
  142. unsigned int irecur,
  143. unsigned int irecur_max,
  144. struct vector3d p0, /* tip */
  145. struct vector3d p1, /* base left */
  146. struct vector3d p2 /* base right */
  147. ){
  148. struct vector3d dif_bmid = VECTOR3D_SINIT();
  149. struct vector3d dif_tmid = VECTOR3D_SINIT();
  150.  
  151. struct vector3d dif_bleft = VECTOR3D_SINIT();
  152. struct vector3d dif_bright = VECTOR3D_SINIT();
  153.  
  154. struct vector3d pt_bmid = VECTOR3D_SINIT();
  155. struct vector3d pt_tmid = VECTOR3D_SINIT();
  156. struct vector3d pt_tamid = VECTOR3D_SINIT();
  157. struct vector3d pt_tamid_cross = VECTOR3D_SINIT();
  158.  
  159. struct vector3d pt_bleft = VECTOR3D_SINIT();
  160. struct vector3d pt_bright = VECTOR3D_SINIT();
  161.  
  162. struct vector3d pt_tleft = VECTOR3D_SINIT();
  163. struct vector3d pt_tright = VECTOR3D_SINIT();
  164.  
  165. double dif_tmid_length = 0.0;
  166. double dif_tmid_scale = (1.0 / (irecur + 1.0)) - 0.1;
  167.  
  168.  
  169. if (irecur >= 3) return;
  170.  
  171.  
  172.  
  173.  
  174. /* Find difference of points p0-p1, and p0-p2 */
  175. dif_bleft = vector_subtract(p0, p1);
  176. dif_bright = vector_subtract(p0, p2);
  177.  
  178.  
  179. /* Find difference of points p1-p2 */
  180. dif_bmid = vector_subtract(p2, p1);
  181.  
  182.  
  183.  
  184.  
  185. /* Find middle of points p1-p2 */
  186. pt_bmid.x = p1.x + dif_bmid.x / 2.0;
  187. pt_bmid.y = p1.y + dif_bmid.y / 2.0;
  188. pt_bmid.z = p1.z + dif_bmid.z / 2.0;
  189.  
  190.  
  191.  
  192. /* Find length and middle of points p0-pt_mid */
  193. dif_tmid = vector_subtract(p0, pt_bmid);
  194. dif_tmid_length = vector_length(p0, pt_bmid);
  195. pt_tmid.x = pt_bmid.x + dif_tmid.x / 2.0;
  196. pt_tmid.y = pt_bmid.y + dif_tmid.y / 2.0;
  197. pt_tmid.z = pt_bmid.z + dif_tmid.z / 2.0;
  198.  
  199.  
  200.  
  201. /* Find base left 1/3 of the way from p1-p0 */
  202. pt_bleft.x = p1.x + dif_bleft.x / 3.0;
  203. pt_bleft.y = p1.y + dif_bleft.y / 3.0;
  204. pt_bleft.z = p1.z + dif_bleft.z / 3.0;
  205.  
  206. /* Find base right 1/3 of the way from p1-p0 */
  207. pt_bright.x = p2.x + dif_bright.x / 3.0;
  208. pt_bright.y = p2.y + dif_bright.y / 3.0;
  209. pt_bright.z = p2.z + dif_bright.z / 3.0;
  210.  
  211.  
  212. /* Find base left 2/3 of the way from p1-p0 */
  213. pt_tleft.x = p1.x + dif_bleft.x / 1.5;
  214. pt_tleft.y = p1.y + dif_bleft.y / 1.5;
  215. pt_tleft.z = p1.z + dif_bleft.z / 1.5;
  216.  
  217. /* Find base right 2/3 of the way from p1-p0 */
  218. pt_tright.x = p2.x + dif_bright.x / 1.5;
  219. pt_tright.y = p2.y + dif_bright.y / 1.5;
  220. pt_tright.z = p2.z + dif_bright.z / 1.5;
  221.  
  222.  
  223.  
  224.  
  225.  
  226. /* Adjust the mid-point tip... ERROR-IN-CHIEF */
  227. pt_tamid_cross = vector_triangle_cross(p0, p1, p2);
  228. pt_tamid_cross = vector_normal(pt_tamid_cross); /* is this correct? */
  229.  
  230. pt_tamid.x = pt_tmid.x + dif_tmid_scale * pt_tamid_cross.x;
  231. pt_tamid.y = pt_tmid.y + dif_tmid_scale * pt_tamid_cross.y;
  232. pt_tamid.z = pt_tmid.z + dif_tmid_scale * pt_tamid_cross.z;
  233.  
  234.  
  235.  
  236. /* Let's add the bottom triangle in purple... */
  237. glColor3f(1.0 - (1.0 / (irecur + 1.0)) / 2.0, 0.5f, 1.0f);
  238. glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
  239. glVertex3f(pt_bleft.x, pt_bleft.y, pt_bleft.z); /* bleft */
  240. glVertex3f(pt_bright.x, pt_bright.y, pt_bright.z); /* bright */
  241.  
  242.  
  243. /* Let's add top triangle in cyan... */
  244. glColor3f(0.0f, 1.0 - (1.0 / (irecur + 1.0)) / 2.0, 1.0f);
  245. glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
  246. glVertex3f(pt_tleft.x, pt_tleft.y, pt_tleft.z); /* bleft */
  247. glVertex3f(pt_tright.x, pt_tright.y, pt_tright.z); /* bright */
  248.  
  249.  
  250. /* Let's add left triangle in white... */
  251. glColor3f(1.0f, 1.0f, 1.0 - (1.0 / (irecur + 1.0)) / 2.0);
  252. glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
  253. glVertex3f(pt_tleft.x, pt_tleft.y, pt_tleft.z); /* bleft */
  254. glVertex3f(pt_bleft.x, pt_bleft.y, pt_bleft.z); /* bright */
  255.  
  256.  
  257. /* Let's add right triangle in oarange... */
  258. glColor3f(1.0 - (1.0 / (irecur + 1.0)) / 2.0, 0.5f, 0.5f);
  259. glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
  260. glVertex3f(pt_bright.x, pt_bright.y, pt_bright.z); /* bleft */
  261. glVertex3f(pt_tright.x, pt_tright.y, pt_tright.z); /* bright */
  262.  
  263.  
  264.  
  265. iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_tleft, pt_bleft); /* bleft */
  266.  
  267. iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_bright, pt_tright); /* bright */
  268.  
  269. iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_tright, pt_tleft); /* btop */
  270.  
  271. iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_bleft, pt_bright); /* bbottom */
  272. }
  273.  
  274.  
  275.  
  276.  
  277.  
  278. void
  279. push_initial_triangles(void)
  280. {
  281. struct vector3d top = VECTOR3D_SINIT_EX(0.0, 1.0, 0.0);
  282.  
  283.  
  284. struct vector3d red_bleft = VECTOR3D_SINIT_EX(-1.0, -1.0, 1.0);
  285. struct vector3d red_bright = VECTOR3D_SINIT_EX(1.0, -1.0, 1.0);
  286.  
  287. struct vector3d green_bleft = VECTOR3D_SINIT_EX(1.0, -1.0, 1.0);
  288. struct vector3d green_bright = VECTOR3D_SINIT_EX(1.0, -1.0, -1.0);
  289.  
  290. struct vector3d blue_bleft = VECTOR3D_SINIT_EX(1.0, -1.0, -1.0);
  291. struct vector3d blue_bright = VECTOR3D_SINIT_EX(-1.0, -1.0, -1.0);
  292.  
  293. struct vector3d yellow_bleft = VECTOR3D_SINIT_EX(-1.0, -1.0, -1.0);
  294. struct vector3d yellow_bright = VECTOR3D_SINIT_EX(-1.0, -1.0, 1.0);
  295.  
  296.  
  297. /* Front - Red */
  298. glColor3f(1.0f, 0.0f, 0.0f);
  299. glVertex3f(top.x, top.y, top.z); /* top */
  300. glVertex3f(red_bleft.x, red_bleft.y, red_bleft.z); /* bleft */
  301. glVertex3f(red_bright.x, red_bright.y, red_bright.z); /* bright */
  302.  
  303. /* Right - Green */
  304. glColor3f(0.0f, 1.0, 0.0);
  305. glVertex3f(top.x, top.y, top.z); /* top */
  306. glVertex3f(green_bleft.x, green_bleft.y, green_bleft.z); /* bleft */
  307. glVertex3f(green_bright.x, green_bright.y, green_bright.z); /* bright */
  308.  
  309. /* Back - Blue */
  310. glColor3f(0.0f, 0.0f, 1.0f);
  311. glVertex3f(0.0f, 1.0f, 0.0f);
  312. glVertex3f(blue_bleft.x, blue_bleft.y, blue_bleft.z);
  313. glVertex3f(blue_bright.x, blue_bright.y, blue_bright.z);
  314.  
  315. /* Left - Yellow */
  316. glColor3f(1.0f, 1.0f, 0.0f);
  317. glVertex3f(0.0f, 1.0f, 0.0f);
  318. glVertex3f(yellow_bleft.x, yellow_bleft.y, yellow_bleft.z);
  319. glVertex3f(yellow_bright.x, yellow_bright.y, yellow_bright.z);
  320.  
  321.  
  322. /* Lets try and iterate the front red face... */
  323. iterate_triangle(0, 0, top, red_bleft, red_bright);
  324.  
  325. /* Lets try and iterate the right green face... */
  326. iterate_triangle(0, 0, top, green_bleft, green_bright);
  327.  
  328. /* Lets try and iterate the back blue face... */
  329. iterate_triangle(0, 0, top, blue_bleft, blue_bright);
  330.  
  331. /* Lets try and iterate the left yellow face... */
  332. iterate_triangle(0, 0, top, yellow_bleft, yellow_bright);
  333. }
  334.  
  335.  
  336.  
  337. void
  338. display_scene(void)
  339. {
  340. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  341. glMatrixMode(GL_MODELVIEW);
  342.  
  343. glLoadIdentity();
  344. glTranslatef(-0.0f, 0.0f, -5.0);
  345. glRotatef(anime_angle_koch, -1.0, 1.0, 0.0);
  346.  
  347. glBegin(GL_TRIANGLES);
  348.  
  349. push_initial_triangles();
  350.  
  351. glEnd();
  352.  
  353. glutSwapBuffers();
  354.  
  355. anime_angle_koch -= 0.2;
  356. }
  357.  
  358.  
  359.  
  360. void
  361. resize_scene(
  362. GLsizei width,
  363. GLsizei height
  364. ){
  365. GLfloat aspect;
  366.  
  367. if (height == 0) height = 1;
  368.  
  369. aspect = (GLfloat)width / (GLfloat)height;
  370.  
  371. glViewport(0, 0, width, height);
  372.  
  373. glMatrixMode(GL_PROJECTION);
  374. glLoadIdentity();
  375.  
  376. gluPerspective(45.0f, aspect, 0.1f, 100.0f);
  377. }
  378.  
  379.  
  380.  
  381.  
  382. int
  383. main(
  384. int argc,
  385. char** argv
  386. ){
  387. glutInit(&argc, argv);
  388. glutInitDisplayMode(GLUT_DOUBLE);
  389.  
  390. glutInitWindowSize(1027, 768);
  391. glutInitWindowPosition(50, 50);
  392. glutCreateWindow(title);
  393.  
  394. glutDisplayFunc(display_scene);
  395. glutReshapeFunc(resize_scene);
  396.  
  397. init_gl();
  398.  
  399. glutTimerFunc(anime_angle_koch_timer, timer_redraw_scene, 0);
  400. glutMainLoop();
  401.  
  402. return 0;
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement