/* CPSC 360 Programming Assignment 4 * 3-D Sierpinski Gasket * by Chris Bolduc * boldu101@chapman.edu */ #include #include #include #include #define DETAIL 2000000 #define WIDTH 20 #define HEIGHT 20 #define DEPTH 20 #define NUM_ITERATIONS 6 #define X 0 #define Y 1 #define Z 2 #define PI 3.1415926535897932384626433832795 // prototypes void drawAxis(); void gasket2d(); void drawGasket2d(float g0[5][3], int iterations); void gasket3d(); void init(){ glClearColor(1.0, 1.0, 1.0, 0.0); glShadeModel(GL_FLAT); //gluOrtho2D(-WIDTH, WIDTH, -HEIGHT, HEIGHT); } // Displays an item void displayItem(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 25.0, 0.0, 1.0, 0.0); gasket3d(); drawAxis(); glFlush(); glutSwapBuffers(); } // Draws the XYZ axis void drawAxis(){ glBegin(GL_LINES); // x is red glColor3f(1, 0, 0); glVertex3f(-WIDTH, 0, 0); glVertex3f(WIDTH, 0, 0); // y is green glColor3f(0, 1, 0); glVertex3f(0, -HEIGHT, 0); glVertex3f(0, HEIGHT, 0); // z is blue glColor3f(0, 0, 1); glVertex3f(0, 0, -DEPTH); glVertex3f(0, 0, DEPTH); glEnd(); } void gasket2d(){ float g0[5][3]; g0[1][X] = -WIDTH; g0[1][Y] = -HEIGHT; g0[2][X] = 0; g0[2][Y] = HEIGHT; g0[3][X] = WIDTH; g0[3][Y] = -HEIGHT; // Draw the solid triangle glColor3f(0.0, 0.0, 0.0); glBegin(GL_TRIANGLES); glVertex2f(g0[1][X], g0[1][Y]); glVertex2f(g0[2][X], g0[2][Y]); glVertex2f(g0[3][X], g0[3][Y]); glEnd(); // Switch color to white and draw internal triangles glColor3f(1.0, 1.0, 1.0); drawGasket2d(g0, NUM_ITERATIONS); } // Draws the white triangles in the gasket void drawGasket2d(float g0[5][3], int iterations){ float g1[5][3], g2[5][3]; int i; if(iterations == 0) return; // Remove the interior middle triangle g1[1][X] = (g0[1][X] + g0[2][X]) / 2; g1[2][X] = (g0[2][X] + g0[3][X]) / 2; g1[3][X] = (g0[1][X] + g0[3][X]) / 2; g1[1][Y] = (g0[1][Y] + g0[2][Y]) / 2; g1[2][Y] = (g0[2][Y] + g0[3][Y]) / 2; g1[3][Y] = (g0[1][Y] + g0[3][Y]) / 2; glBegin(GL_TRIANGLES); glVertex2f(g1[1][X], g1[1][Y]); glVertex2f(g1[2][X], g1[2][Y]); glVertex2f(g1[3][X], g1[3][Y]); glEnd(); // Now draw the three other small triangles g2[1][X] = g0[1][X]; g2[1][Y] = g0[1][Y]; g2[2][X] = g1[1][X]; g2[2][Y] = g1[1][Y]; g2[3][X] = g1[3][X]; g2[3][Y] = g1[3][Y]; drawGasket2d(g2, iterations - 1); // We don't need g2 anymore, so we can use it again here g2[1][X] = g1[1][X]; g2[1][Y] = g1[1][Y]; g2[2][X] = g0[2][X]; g2[2][Y] = g0[2][Y]; g2[3][X] = g1[2][X]; g2[3][Y] = g1[2][Y]; drawGasket2d(g2, iterations - 1); g2[1][X] = g1[3][X]; g2[1][Y] = g1[3][Y]; g2[2][X] = g1[2][X]; g2[2][Y] = g1[2][Y]; g2[3][X] = g0[3][X]; g2[3][Y] = g0[3][Y]; drawGasket2d(g2, iterations - 1); } void gasket3d(){ float p0[3] = { 2.0, -3.0, 5 }; float p1[3]; float v0[3] = { -WIDTH, -HEIGHT, 0 }; float v1[3] = { 0, HEIGHT, 0 }; float v2[3] = { WIDTH, -HEIGHT, 0 }; float v3[3] = { 0, 0, DEPTH }; int currVert = 0; int i; // Draw the solid triangle glColor3f(1.0, 0.0, 0.0); glBegin(GL_POINTS); glVertex3f(v0[0], v0[1], v0[2]); glVertex3f(v1[0], v1[1], v1[2]); glVertex3f(v2[0], v2[1], v2[2]); glVertex3f(v3[0], v3[1], v3[2]); glEnd(); glColor3f(1.0, 0.0, 0.0); for(i = 0; i != DETAIL; ++i){ switch(currVert){ case 0: p1[0] = (p0[0] + v0[0]) / 2; p1[1] = (p0[1] + v0[1]) / 2; p1[2] = (p0[2] + v0[2]) / 2; break; case 1: p1[0] = (p0[0] + v1[0]) / 2; p1[1] = (p0[1] + v1[1]) / 2; p1[2] = (p0[2] + v1[2]) / 2; break; case 2: p1[0] = (p0[0] + v2[0]) / 2; p1[1] = (p0[1] + v2[1]) / 2; p1[2] = (p0[2] + v2[2]) / 2; break; case 3: p1[0] = (p0[0] + v3[0]) / 2; p1[1] = (p0[1] + v3[1]) / 2; p1[2] = (p0[2] + v3[2]) / 2; break; } glBegin(GL_POINTS); glVertex3f(p1[0], p1[1], p1[2]); glEnd(); p0[0] = p1[0]; p0[1] = p1[1]; p0[2] = p1[2]; currVert = rand() % 4; } } void winReshapeFcn(int newWidth, int newHeight){ glViewport(0, 0, (GLsizei)newWidth, (GLsizei)newHeight); glDepthRange(0.0, 100.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 25); glMatrixMode(GL_MODELVIEW); } int main(int argc, char *argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50, 100); glutInitWindowSize(800, 600); glutCreateWindow("Example OpenGL Program"); init(); glutDisplayFunc(displayItem); glutReshapeFunc(winReshapeFcn); glutMainLoop(); return 0; }