/* Two-Dimensional Sierpinski Gasket */ /* Generated Using Randomly Selected Vertices */ /* And Bisection */ #ifdef mac_osx #include // GLUT for the Macintosh #else #include // GLUT for Linux and Unix. #endif /* Initial dimensions and attributes of the GUI Window */ #define INITIAL_WINDOW_WIDTH 512 #define INITIAL_WINDOW_HEIGHT 512 #define INITIAL_HORIZONTAL_OFFSET 10 #define INITIAL_VERTICAL_OFFSET 40 #define WINDOW_TITLE "Sierpinski Gasket" /* World coordinate extrema */ #define XMIN 0.0 #define XMAX 500.0 #define YMIN 0.0 #define YMAX 500.0 /* Algorithm parameter */ #define MAX_ITERATIONS 100000 /* Global variables */ int windowWidth = INITIAL_WINDOW_WIDTH; int windowHeight = INITIAL_WINDOW_HEIGHT; /* Function prototypes */ void display(void); void reshape(int w, int h); /* reshape is called each time the user changes the GUI window dimensions. It updates the viewport and the world coordinate -> device coordinate transformation */ void reshape(int w, int h) { windowWidth = w; /* Update the GUI window dimensions */ windowHeight = h; /* We will draw in the entire window */ glViewport(0, 0, (GLsizei) windowWidth, (GLsizei) windowHeight); /* using an orthographic projection */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(XMIN, XMAX, YMIN, YMAX); glMatrixMode(GL_MODELVIEW); glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */ glColor3f(1.0, 0.0, 0.0); /* draw in red */ } /* display is called each time a portion of the window is exposed, or the window is resized. It is always called after reshape. It generates a recursive illustration of Sierpinski's triangular gasket. */ void display( void ) { /* define a point data type */ typedef GLfloat point2[2]; point2 vertices[3]={{XMIN, YMIN},{(XMIN+XMAX)/2, YMAX},{XMAX, YMIN}}; /* The boundary triangle */ int j, k; int rand(); /* standard random number generator */ point2 p = {(XMIN + XMAX)/2, YMIN}; /* An initial point (world coordinate) */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window (paint it with the background color)*/ /* compute and plot MAX_INTERATIONS new points */ for( k=0; k < MAX_ITERATIONS; k++) { j=rand() % 3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0] + vertices[j][0]) / 2.0; p[1] = (p[1] + vertices[j][1]) / 2.0; /* plot one new point each iteration */ glBegin(GL_POINTS); glVertex2fv(p); glEnd(); } glFlush(); /* clear buffers */ } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ glutInitWindowSize(INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT); glutInitWindowPosition(INITIAL_HORIZONTAL_OFFSET, INITIAL_VERTICAL_OFFSET); glutCreateWindow(WINDOW_TITLE); glutReshapeFunc(reshape); /* register reshape as a callback function */ glutDisplayFunc(display); /* register display as a callback function */ glutMainLoop(); /* enter event loop */ return 0; }