Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/freeglut/progs/demos/Fractals_random/fractals_random.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* fractals_random.c */ | |
| 2 /* This demo shows a single-buffering "freeglut" example. */ | |
| 3 | |
| 4 /* | |
| 5 * Program to draw a fractal by Michael Barnsley's stochastic algorithm. | |
| 6 * Algorithm: | |
| 7 * (1) Define the affine transformations (of the form r(i+1) = A r(i) + b ) | |
| 8 * (2) Find the stationary point for the first transformation | |
| 9 * (3) To draw: | |
| 10 * - Pick a random integer between 1 and the number of transformations (inclusive) | |
| 11 * - Send the current point through the transformation to create the new current point | |
| 12 * - Plot the new current point | |
| 13 */ | |
| 14 | |
| 15 /* | |
| 16 * User Commands: | |
| 17 * PgUp, PgDn - increase/decrease scaling | |
| 18 * Arrow keys - translate viewing section | |
| 19 * r - reset view | |
| 20 * Escape - quit | |
| 21 */ | |
| 22 | |
| 23 #include <GL/freeglut.h> | |
| 24 #include <stdio.h> | |
| 25 #include <stdlib.h> | |
| 26 #include <string.h> | |
| 27 #include <math.h> | |
| 28 #define FGH_PI 3.14159265358979323846 | |
| 29 #ifdef _MSC_VER | |
| 30 /* DUMP MEMORY LEAKS */ | |
| 31 #include <crtdbg.h> | |
| 32 #endif | |
| 33 | |
| 34 typedef struct | |
| 35 { | |
| 36 double a00, a01, a10, a11 ; /* Transformation matrix */ | |
| 37 double b0, b1 ; /* Constant vector added on */ | |
| 38 double statx, staty ; /* Coordinates of the stationary point */ | |
| 39 } | |
| 40 AffineTrans ; | |
| 41 | |
| 42 /* Number of levels to draw the fractal */ | |
| 43 static int num_levels = 0 ; | |
| 44 | |
| 45 /* The definition of the fractal */ | |
| 46 static int num_trans ; | |
| 47 static AffineTrans *affine ; | |
| 48 | |
| 49 /* the window title */ | |
| 50 char window_title [ 80 ] ; | |
| 51 | |
| 52 /* The amount the view is translated */ | |
| 53 double xwin = 0.0, ywin = 0.0 ; | |
| 54 double scale_factor = 1.0 ; | |
| 55 | |
| 56 /* The current point */ | |
| 57 double current_x = 0.0, current_y = 0.0 ; | |
| 58 | |
| 59 /* Signals when a glClear is needed */ | |
| 60 static GLboolean needClear = GL_TRUE; | |
| 61 | |
| 62 static void draw_level ( int num, double m00, double m01, double m10, double m11, double n0, double n1 ) | |
| 63 { | |
| 64 /* Draw a fractal transformed by "M", "N" as passed in */ | |
| 65 int i ; | |
| 66 | |
| 67 for ( i = 0; i < 10; i++ ) | |
| 68 { | |
| 69 int random = ( rand( ) >> 10 ) % num_trans; | |
| 70 double new_x = affine[random].a00 * current_x + affine[random].a01 * current_y + affine[random].b0 ; | |
| 71 double new_y = affine[random].a10 * current_x + affine[random].a11 * current_y + affine[random].b1 ; | |
| 72 | |
| 73 glVertex2d ( new_x, new_y ) ; | |
| 74 current_x = new_x ; | |
| 75 current_y = new_y ; | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 static void | |
| 80 Display(void) | |
| 81 { | |
| 82 if (needClear) { | |
| 83 glClear(GL_COLOR_BUFFER_BIT); | |
| 84 needClear = GL_FALSE; | |
| 85 } | |
| 86 | |
| 87 /* the curve */ | |
| 88 glPushMatrix(); | |
| 89 glScaled(2.5, 2.5, 2.5); | |
| 90 | |
| 91 glColor4f(0.0, 0.0, 0.0, 1.0); | |
| 92 glBegin ( GL_POINTS ) ; | |
| 93 draw_level ( num_levels, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 ); | |
| 94 glEnd () ; | |
| 95 | |
| 96 glPopMatrix(); | |
| 97 | |
| 98 glFlush(); | |
| 99 glutPostRedisplay(); /* Needed so that this function will be called again */ | |
| 100 } | |
| 101 | |
| 102 static void | |
| 103 Reshape(int width, int height) | |
| 104 { | |
| 105 float ar; | |
| 106 glViewport(0, 0, width, height); | |
| 107 glMatrixMode(GL_PROJECTION); | |
| 108 glLoadIdentity(); | |
| 109 ar = (float) width / (float) height; | |
| 110 if( ar > 1 ) | |
| 111 glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0); | |
| 112 else | |
| 113 glFrustum(-1.0, 1.0, -1/ar, 1/ar, 2.0, 100.0); | |
| 114 glMatrixMode(GL_MODELVIEW); | |
| 115 glLoadIdentity(); | |
| 116 xwin = -1.0 ; | |
| 117 ywin = 0.0 ; | |
| 118 glTranslated(xwin, ywin, -5.0); | |
| 119 needClear = GL_TRUE; | |
| 120 } | |
| 121 | |
| 122 static void | |
| 123 Key(unsigned char key, int x, int y) | |
| 124 { | |
| 125 int changed_settings = 1; | |
| 126 | |
| 127 switch (key) { | |
| 128 case 27: /* Escape key */ | |
| 129 glutLeaveMainLoop (); | |
| 130 break; | |
| 131 | |
| 132 case 'r' : case 'R' : | |
| 133 glMatrixMode(GL_MODELVIEW); | |
| 134 glLoadIdentity(); | |
| 135 xwin = -1.0 ; | |
| 136 ywin = 0.0 ; | |
| 137 glTranslated(xwin, ywin, -5.0); | |
| 138 break ; | |
| 139 | |
| 140 default: | |
| 141 changed_settings = 0; | |
| 142 break; | |
| 143 } | |
| 144 if (changed_settings) | |
| 145 needClear = GL_TRUE; | |
| 146 glutPostRedisplay(); | |
| 147 } | |
| 148 | |
| 149 static void | |
| 150 Special(int key, int x, int y) | |
| 151 { | |
| 152 int changed_settings = 1; | |
| 153 | |
| 154 switch (key) { | |
| 155 case GLUT_KEY_UP : | |
| 156 glMatrixMode(GL_MODELVIEW); | |
| 157 ywin += 0.1 * scale_factor ; | |
| 158 glTranslated(0.0, 0.1 * scale_factor, 0.0); | |
| 159 break ; | |
| 160 | |
| 161 case GLUT_KEY_DOWN : | |
| 162 glMatrixMode(GL_MODELVIEW); | |
| 163 ywin -= 0.1 * scale_factor ; | |
| 164 glTranslated(0.0, -0.1 * scale_factor, 0.0); | |
| 165 break ; | |
| 166 | |
| 167 case GLUT_KEY_LEFT : | |
| 168 glMatrixMode(GL_MODELVIEW); | |
| 169 xwin -= 0.1 * scale_factor ; | |
| 170 glTranslated(-0.1 * scale_factor, 0.0, 0.0); | |
| 171 break ; | |
| 172 | |
| 173 case GLUT_KEY_RIGHT : | |
| 174 glMatrixMode(GL_MODELVIEW); | |
| 175 xwin += 0.1 * scale_factor ; | |
| 176 glTranslated(0.1 * scale_factor, 0.0, 0.0); | |
| 177 break ; | |
| 178 | |
| 179 case GLUT_KEY_PAGE_UP : | |
| 180 glMatrixMode(GL_MODELVIEW); | |
| 181 glTranslated ( -xwin, -ywin, 0.0 ) ; | |
| 182 glScaled(1.25, 1.25, 1.25); | |
| 183 glTranslated ( xwin, ywin, 0.0 ) ; | |
| 184 scale_factor *= 0.8 ; | |
| 185 break ; | |
| 186 | |
| 187 case GLUT_KEY_PAGE_DOWN : | |
| 188 glMatrixMode(GL_MODELVIEW); | |
| 189 glTranslated ( -xwin, -ywin, 0.0 ) ; | |
| 190 glScaled(0.8, 0.8, 0.8); | |
| 191 glTranslated ( xwin, ywin, 0.0 ) ; | |
| 192 scale_factor *= 1.25 ; | |
| 193 break ; | |
| 194 | |
| 195 default: | |
| 196 changed_settings = 0; | |
| 197 break; | |
| 198 } | |
| 199 if (changed_settings) | |
| 200 needClear = GL_TRUE; | |
| 201 | |
| 202 glutPostRedisplay(); | |
| 203 } | |
| 204 | |
| 205 | |
| 206 static int mouse_x = 0, mouse_y = 0 ; | |
| 207 static int button_down = GLUT_DOWN ; | |
| 208 | |
| 209 static void | |
| 210 Mouse ( int button, int updown, int x, int y ) | |
| 211 { | |
| 212 button_down = updown ; | |
| 213 | |
| 214 if ( updown == GLUT_DOWN ) | |
| 215 { | |
| 216 mouse_x = x ; | |
| 217 mouse_y = y ; | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 static void | |
| 222 MouseMotion ( int x, int y ) | |
| 223 { | |
| 224 int window_width = glutGet ( GLUT_WINDOW_WIDTH ) ; | |
| 225 int window_height = glutGet ( GLUT_WINDOW_HEIGHT ) ; | |
| 226 int window_size = ( window_width < window_height ) ? window_width : window_height ; | |
| 227 | |
| 228 double delta_x = 5.0 * (double)(x - mouse_x) / (double)(window_size) ; | |
| 229 double delta_y = 5.0 * (double)(y - mouse_y) / (double)(window_size) ; | |
| 230 | |
| 231 xwin += delta_x * scale_factor ; | |
| 232 ywin -= delta_y * scale_factor ; | |
| 233 glMatrixMode ( GL_MODELVIEW ) ; | |
| 234 glTranslated ( delta_x * scale_factor, -delta_y * scale_factor, 0.0 ) ; | |
| 235 | |
| 236 needClear = GL_TRUE; | |
| 237 glutPostRedisplay(); | |
| 238 | |
| 239 mouse_x = x ; | |
| 240 mouse_y = y ; | |
| 241 } | |
| 242 | |
| 243 static void | |
| 244 MouseWheel ( int wheel_number, int direction, int x, int y ) | |
| 245 { | |
| 246 double scale = ( direction > 0 ) ? 1.25 : 0.8 ; | |
| 247 | |
| 248 glMatrixMode ( GL_MODELVIEW ) ; | |
| 249 glTranslated ( -xwin, -ywin, 0.0 ) ; | |
| 250 glScaled ( scale, scale, scale ) ; | |
| 251 glTranslated ( xwin, ywin, 0.0 ) ; | |
| 252 scale_factor /= scale ; | |
| 253 | |
| 254 needClear = GL_TRUE; | |
| 255 glutPostRedisplay(); | |
| 256 } | |
| 257 | |
| 258 | |
| 259 static void | |
| 260 checkedFGets ( char *s, int size, FILE *stream ) | |
| 261 { | |
| 262 if ( fgets ( s, size, stream ) == NULL ) { | |
| 263 fprintf ( stderr, "fgets failed\n"); | |
| 264 exit ( EXIT_FAILURE ); | |
| 265 } | |
| 266 } | |
| 267 | |
| 268 | |
| 269 void readConfigFile ( char *fnme ) | |
| 270 { | |
| 271 FILE *fptr = fopen ( fnme, "rt" ) ; | |
| 272 int i ; | |
| 273 char inputline [ 256 ] ; | |
| 274 | |
| 275 if ( fptr ) | |
| 276 { | |
| 277 /* Read a header line */ | |
| 278 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 279 | |
| 280 /* Read a comment line */ | |
| 281 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 282 | |
| 283 /* Read the window title */ | |
| 284 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 285 /* We assume here that this line will not exceed 79 characters plus a | |
| 286 newline (window_title is 80 characters long). That'll cause a buffer | |
| 287 overflow. For a simple program like this, though, we're letting it | |
| 288 slide! | |
| 289 */ | |
| 290 sscanf ( inputline, "%[a-zA-Z0-9!@#$%^&*()+=/\\_-\" ]", window_title ) ; | |
| 291 | |
| 292 /* Read a comment line */ | |
| 293 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 294 | |
| 295 /* Read the number of affine transformations */ | |
| 296 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 297 sscanf ( inputline, "%d", &num_trans ) ; | |
| 298 | |
| 299 affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ; | |
| 300 | |
| 301 /* Read a comment line */ | |
| 302 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 303 | |
| 304 for ( i = 0; i < num_trans; i++ ) | |
| 305 { | |
| 306 /* Read an affine transformation definition */ | |
| 307 checkedFGets ( inputline, sizeof ( inputline ), fptr ) ; | |
| 308 sscanf ( inputline, "%lf %lf %lf %lf %lf %lf", &affine[i].a00, &affine[i].a01, | |
| 309 &affine[i].a10, &affine[i].a11, &affine[i].b0, &affine[i].b1 ) ; | |
| 310 } | |
| 311 } | |
| 312 else /* No data file, set a default */ | |
| 313 { | |
| 314 printf ( "ERROR opening file <%s>\n", fnme ) ; | |
| 315 strcpy ( window_title, "Koch Snowflake" ) ; | |
| 316 num_trans = 4 ; | |
| 317 affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ; | |
| 318 affine[0].a00 = 1/3. ; affine[0].a01 = 0.00 ; affine[0].a10 = 0.00 ; affine[0].a11 = 1/3. ; | |
| 319 affine[0].b0 = 0.0 ; affine[0].b1 = 0.0 ; | |
| 320 | |
| 321 affine[1].a00 = 1/6. ; affine[1].a01 = -1/3.*sin(FGH_PI/3.) ; affine[1].a10 = 1/3.*sin(FGH_PI/3.) ; affine[1].a11 = 1/6. ; | |
| 322 affine[1].b0 = 1/3. ; affine[1].b1 = 0.0 ; | |
| 323 | |
| 324 affine[2].a00 = 1/6. ; affine[2].a01 = -1/3.*sin(-FGH_PI/3.) ; affine[2].a10 = 1/3.*sin(-FGH_PI/3.) ; affine[2].a11 = 1/6. ; | |
| 325 affine[2].b0 = 0.5 ; affine[2].b1 = sqrt(3)/6. ; | |
| 326 | |
| 327 affine[3].a00 = 1/3. ; affine[3].a01 = 0.00 ; affine[3].a10 = 0.00 ; affine[3].a11 = 1/3. ; | |
| 328 affine[3].b0 = 2/3. ; affine[3].b1 = 0.0 ; | |
| 329 } | |
| 330 | |
| 331 for ( i = 0; i < num_trans; i++ ) | |
| 332 { | |
| 333 double m00, m01, m10, m11 ; /* Matrix "I" minus "A" */ | |
| 334 double determ ; /* Determinant of this matrix */ | |
| 335 | |
| 336 /* Calculate the stationary point */ | |
| 337 | |
| 338 m00 = 1.0 - affine[i].a00 ; | |
| 339 m01 = - affine[i].a01 ; | |
| 340 m10 = - affine[i].a10 ; | |
| 341 m11 = 1.0 - affine[i].a11 ; | |
| 342 | |
| 343 determ = m00 * m11 - m01 * m10 ; | |
| 344 | |
| 345 if ( fabs ( determ ) > 1.e-6 ) | |
| 346 { | |
| 347 affine[i].statx = ( m11 * affine[i].b0 - m01 * affine[i].b1 ) / determ ; | |
| 348 affine[i].staty = ( -m10 * affine[i].b0 + m00 * affine[i].b1 ) / determ ; | |
| 349 } | |
| 350 else | |
| 351 affine[i].statx = affine[i].staty = 0.0 ; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 int | |
| 356 main(int argc, char *argv[]) | |
| 357 { | |
| 358 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE ); | |
| 359 | |
| 360 glutInitWindowSize(500, 250); | |
| 361 glutInitWindowPosition ( 140, 140 ) ; | |
| 362 glutInit(&argc, argv); | |
| 363 | |
| 364 if ( argc > 1 ) | |
| 365 readConfigFile ( argv[1] ) ; | |
| 366 else | |
| 367 readConfigFile ( "fractals.dat" ) ; | |
| 368 | |
| 369 glutCreateWindow( window_title ); | |
| 370 | |
| 371 glClearColor(1.0, 1.0, 1.0, 1.0); | |
| 372 | |
| 373 glutReshapeFunc(Reshape); | |
| 374 glutKeyboardFunc(Key); | |
| 375 glutSpecialFunc(Special); | |
| 376 glutDisplayFunc(Display); | |
| 377 glutMouseFunc(Mouse); | |
| 378 glutMotionFunc(MouseMotion); | |
| 379 glutMouseWheelFunc(MouseWheel); | |
| 380 | |
| 381 glutMainLoop(); | |
| 382 | |
| 383 printf ( "Back from the 'freeglut' main loop\n" ) ; | |
| 384 | |
| 385 free ( affine ) ; | |
| 386 | |
| 387 #ifdef _MSC_VER | |
| 388 /* DUMP MEMORY LEAK INFORMATION */ | |
| 389 _CrtDumpMemoryLeaks () ; | |
| 390 #endif | |
| 391 | |
| 392 return 0; /* ANSI C requires main to return int. */ | |
| 393 } |
