Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <glut.h>
- #include <math.h>
- struct vector3d
- {
- GLfloat x;
- GLfloat y;
- GLfloat z;
- };
- #define VECTOR3D_SINIT_EX(mp_x, mp_y, mp_z) { mp_x, mp_y, mp_z }
- #define VECTOR3D_SINIT() VECTOR3D_SINIT_EX(0.0, 0.0, 0.0)
- struct color
- {
- GLfloat r;
- GLfloat g;
- GLfloat b;
- };
- static char title[] = "3D von Koch Curve";
- static GLfloat anime_angle_koch = 1.0;
- static int anime_angle_koch_timer = 15.0;
- void
- timer_redraw_scene(
- int value
- ){
- glutPostRedisplay();
- glutTimerFunc(anime_angle_koch_timer, timer_redraw_scene, 0);
- }
- struct vector3d
- vector_subtract(
- struct vector3d p0,
- struct vector3d p1
- ){
- struct vector3d np;
- np.x = p0.x - p1.x;
- np.y = p0.y - p1.y;
- np.z = p0.z - p1.z;
- return np;
- }
- double
- vector_length(
- struct vector3d p0,
- struct vector3d p1
- ){
- struct vector3d dif = vector_subtract(p0, p1);
- return sqrt(dif.x * dif.x + dif.y * dif.y + dif.z * dif.z);
- }
- struct vector3d
- vector_normal(
- struct vector3d p
- ){
- struct vector3d np = VECTOR3D_SINIT();
- double length = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
- if (length != 0.0)
- {
- np.x = p.x / length;
- np.y = p.y / length;
- np.z = p.z / length;
- }
- return np;
- }
- struct vector3d
- vector_cross(
- struct vector3d p0,
- struct vector3d p1
- ){
- struct vector3d np;
- np.x = p0.y * p1.z - p0.z * p1.y;
- np.y = p0.z * p1.x - p0.x * p1.z;
- np.z = p0.x * p1.y - p0.y * p1.x;
- return np;
- }
- struct vector3d
- vector_triangle_cross(
- struct vector3d p0,
- struct vector3d p1,
- struct vector3d p2
- ){
- struct vector3d e0 = vector_subtract(p0, p1);
- struct vector3d e1 = vector_subtract(p1, p2);
- struct vector3d np = vector_cross(e0, e1);
- return np;
- }
- void
- init_gl()
- {
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClearDepth(1.0f);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glShadeModel(GL_FLAT);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- }
- void
- iterate_triangle(
- unsigned int irecur,
- unsigned int irecur_max,
- struct vector3d p0, /* tip */
- struct vector3d p1, /* base left */
- struct vector3d p2 /* base right */
- ){
- struct vector3d dif_bmid = VECTOR3D_SINIT();
- struct vector3d dif_tmid = VECTOR3D_SINIT();
- struct vector3d dif_bleft = VECTOR3D_SINIT();
- struct vector3d dif_bright = VECTOR3D_SINIT();
- struct vector3d pt_bmid = VECTOR3D_SINIT();
- struct vector3d pt_tmid = VECTOR3D_SINIT();
- struct vector3d pt_tamid = VECTOR3D_SINIT();
- struct vector3d pt_tamid_cross = VECTOR3D_SINIT();
- struct vector3d pt_bleft = VECTOR3D_SINIT();
- struct vector3d pt_bright = VECTOR3D_SINIT();
- struct vector3d pt_tleft = VECTOR3D_SINIT();
- struct vector3d pt_tright = VECTOR3D_SINIT();
- double dif_tmid_length = 0.0;
- double dif_tmid_scale = (1.0 / (irecur + 1.0)) - 0.1;
- if (irecur >= 3) return;
- /* Find difference of points p0-p1, and p0-p2 */
- dif_bleft = vector_subtract(p0, p1);
- dif_bright = vector_subtract(p0, p2);
- /* Find difference of points p1-p2 */
- dif_bmid = vector_subtract(p2, p1);
- /* Find middle of points p1-p2 */
- pt_bmid.x = p1.x + dif_bmid.x / 2.0;
- pt_bmid.y = p1.y + dif_bmid.y / 2.0;
- pt_bmid.z = p1.z + dif_bmid.z / 2.0;
- /* Find length and middle of points p0-pt_mid */
- dif_tmid = vector_subtract(p0, pt_bmid);
- dif_tmid_length = vector_length(p0, pt_bmid);
- pt_tmid.x = pt_bmid.x + dif_tmid.x / 2.0;
- pt_tmid.y = pt_bmid.y + dif_tmid.y / 2.0;
- pt_tmid.z = pt_bmid.z + dif_tmid.z / 2.0;
- /* Find base left 1/3 of the way from p1-p0 */
- pt_bleft.x = p1.x + dif_bleft.x / 3.0;
- pt_bleft.y = p1.y + dif_bleft.y / 3.0;
- pt_bleft.z = p1.z + dif_bleft.z / 3.0;
- /* Find base right 1/3 of the way from p1-p0 */
- pt_bright.x = p2.x + dif_bright.x / 3.0;
- pt_bright.y = p2.y + dif_bright.y / 3.0;
- pt_bright.z = p2.z + dif_bright.z / 3.0;
- /* Find base left 2/3 of the way from p1-p0 */
- pt_tleft.x = p1.x + dif_bleft.x / 1.5;
- pt_tleft.y = p1.y + dif_bleft.y / 1.5;
- pt_tleft.z = p1.z + dif_bleft.z / 1.5;
- /* Find base right 2/3 of the way from p1-p0 */
- pt_tright.x = p2.x + dif_bright.x / 1.5;
- pt_tright.y = p2.y + dif_bright.y / 1.5;
- pt_tright.z = p2.z + dif_bright.z / 1.5;
- /* Adjust the mid-point tip... ERROR-IN-CHIEF */
- pt_tamid_cross = vector_triangle_cross(p0, p1, p2);
- pt_tamid_cross = vector_normal(pt_tamid_cross); /* is this correct? */
- pt_tamid.x = pt_tmid.x + dif_tmid_scale * pt_tamid_cross.x;
- pt_tamid.y = pt_tmid.y + dif_tmid_scale * pt_tamid_cross.y;
- pt_tamid.z = pt_tmid.z + dif_tmid_scale * pt_tamid_cross.z;
- /* Let's add the bottom triangle in purple... */
- glColor3f(1.0 - (1.0 / (irecur + 1.0)) / 2.0, 0.5f, 1.0f);
- glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
- glVertex3f(pt_bleft.x, pt_bleft.y, pt_bleft.z); /* bleft */
- glVertex3f(pt_bright.x, pt_bright.y, pt_bright.z); /* bright */
- /* Let's add top triangle in cyan... */
- glColor3f(0.0f, 1.0 - (1.0 / (irecur + 1.0)) / 2.0, 1.0f);
- glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
- glVertex3f(pt_tleft.x, pt_tleft.y, pt_tleft.z); /* bleft */
- glVertex3f(pt_tright.x, pt_tright.y, pt_tright.z); /* bright */
- /* Let's add left triangle in white... */
- glColor3f(1.0f, 1.0f, 1.0 - (1.0 / (irecur + 1.0)) / 2.0);
- glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
- glVertex3f(pt_tleft.x, pt_tleft.y, pt_tleft.z); /* bleft */
- glVertex3f(pt_bleft.x, pt_bleft.y, pt_bleft.z); /* bright */
- /* Let's add right triangle in oarange... */
- glColor3f(1.0 - (1.0 / (irecur + 1.0)) / 2.0, 0.5f, 0.5f);
- glVertex3f(pt_tamid.x, pt_tamid.y, pt_tamid.z); /* top */
- glVertex3f(pt_bright.x, pt_bright.y, pt_bright.z); /* bleft */
- glVertex3f(pt_tright.x, pt_tright.y, pt_tright.z); /* bright */
- iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_tleft, pt_bleft); /* bleft */
- iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_bright, pt_tright); /* bright */
- iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_tright, pt_tleft); /* btop */
- iterate_triangle(irecur + 1, irecur_max, pt_tamid, pt_bleft, pt_bright); /* bbottom */
- }
- void
- push_initial_triangles(void)
- {
- struct vector3d top = VECTOR3D_SINIT_EX(0.0, 1.0, 0.0);
- struct vector3d red_bleft = VECTOR3D_SINIT_EX(-1.0, -1.0, 1.0);
- struct vector3d red_bright = VECTOR3D_SINIT_EX(1.0, -1.0, 1.0);
- struct vector3d green_bleft = VECTOR3D_SINIT_EX(1.0, -1.0, 1.0);
- struct vector3d green_bright = VECTOR3D_SINIT_EX(1.0, -1.0, -1.0);
- struct vector3d blue_bleft = VECTOR3D_SINIT_EX(1.0, -1.0, -1.0);
- struct vector3d blue_bright = VECTOR3D_SINIT_EX(-1.0, -1.0, -1.0);
- struct vector3d yellow_bleft = VECTOR3D_SINIT_EX(-1.0, -1.0, -1.0);
- struct vector3d yellow_bright = VECTOR3D_SINIT_EX(-1.0, -1.0, 1.0);
- /* Front - Red */
- glColor3f(1.0f, 0.0f, 0.0f);
- glVertex3f(top.x, top.y, top.z); /* top */
- glVertex3f(red_bleft.x, red_bleft.y, red_bleft.z); /* bleft */
- glVertex3f(red_bright.x, red_bright.y, red_bright.z); /* bright */
- /* Right - Green */
- glColor3f(0.0f, 1.0, 0.0);
- glVertex3f(top.x, top.y, top.z); /* top */
- glVertex3f(green_bleft.x, green_bleft.y, green_bleft.z); /* bleft */
- glVertex3f(green_bright.x, green_bright.y, green_bright.z); /* bright */
- /* Back - Blue */
- glColor3f(0.0f, 0.0f, 1.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glVertex3f(blue_bleft.x, blue_bleft.y, blue_bleft.z);
- glVertex3f(blue_bright.x, blue_bright.y, blue_bright.z);
- /* Left - Yellow */
- glColor3f(1.0f, 1.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
- glVertex3f(yellow_bleft.x, yellow_bleft.y, yellow_bleft.z);
- glVertex3f(yellow_bright.x, yellow_bright.y, yellow_bright.z);
- /* Lets try and iterate the front red face... */
- iterate_triangle(0, 0, top, red_bleft, red_bright);
- /* Lets try and iterate the right green face... */
- iterate_triangle(0, 0, top, green_bleft, green_bright);
- /* Lets try and iterate the back blue face... */
- iterate_triangle(0, 0, top, blue_bleft, blue_bright);
- /* Lets try and iterate the left yellow face... */
- iterate_triangle(0, 0, top, yellow_bleft, yellow_bright);
- }
- void
- display_scene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(-0.0f, 0.0f, -5.0);
- glRotatef(anime_angle_koch, -1.0, 1.0, 0.0);
- glBegin(GL_TRIANGLES);
- push_initial_triangles();
- glEnd();
- glutSwapBuffers();
- anime_angle_koch -= 0.2;
- }
- void
- resize_scene(
- GLsizei width,
- GLsizei height
- ){
- GLfloat aspect;
- if (height == 0) height = 1;
- aspect = (GLfloat)width / (GLfloat)height;
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(45.0f, aspect, 0.1f, 100.0f);
- }
- int
- main(
- int argc,
- char** argv
- ){
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE);
- glutInitWindowSize(1027, 768);
- glutInitWindowPosition(50, 50);
- glutCreateWindow(title);
- glutDisplayFunc(display_scene);
- glutReshapeFunc(resize_scene);
- init_gl();
- glutTimerFunc(anime_angle_koch_timer, timer_redraw_scene, 0);
- glutMainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement