|
|
1.1 ! root 1: /*** Mandel.c - compute and display Mandelbrot set ! 2: * R. A. Garmoe 86/12/10 ! 3: */ ! 4: ! 5: ! 6: ! 7: /** Mandel compute the elements of the Mandelbrot set ! 8: * ! 9: * z = z**2 + c ! 10: * ! 11: * where z and c are in the complex plane and z = 0 + 0i for the first ! 12: * iteration. The elements of the set along with the description of the ! 13: * computation are written to the .cnt file. ! 14: */ ! 15: ! 16: ! 17: ! 18: ! 19: /** Call ! 20: * ! 21: * mandel -v {-u a+bi} {-l c+di} {-r num} {-c num} {-i itr} {-a f} {-f name} ! 22: * {-d display} ! 23: * ! 24: * where ! 25: * ! 26: * a compute each point with an aspect ratio of f where ! 27: * f is : ! 28: * f.ffff floating point number describing the ! 29: * ratio of width vs height of each pixel ! 30: * ! 31: * c number of points across the real coordinate. This ! 32: * value cannot exceed 2000 and is defaulted to 640. ! 33: * ! 34: * d set display to device. The default display is EGA. ! 35: * CGA Color Graphics Adapter ! 36: * columns = 350 ! 37: * rows = 200 ! 38: * aspect = 2.4 ! 39: * ! 40: * EGA Extended Graphics Adapter ! 41: * columns = 640 ! 42: * rows = 350 ! 43: * aspect = 2.4 ! 44: * ! 45: * PGA Professional Graphics Adapter ! 46: * columns = 640 ! 47: * rows = 480 ! 48: * aspect = 1.0 ! 49: * ! 50: * f name for the .cnt file ! 51: * If name is not specified, "mandel" is used. ! 52: * ! 53: * i iteration limit. This value cannot exceed 1000 and ! 54: * the default is 256 ! 55: * ! 56: * l lower right corner as c+di ! 57: * ! 58: * ! 59: * r number of points down the imaginary coordinate. This ! 60: * value is defaulted to 350. ! 61: * ! 62: * u upper left corner as a+bi ! 63: * ! 64: * v display information about each scan line as processed ! 65: * ! 66: * The .cnt file has the format ! 67: * int number of points along the real axis ! 68: * int number of points along the imaginary axis ! 69: * int maximum iteration point for each point ! 70: * double real coordinate of upper left ! 71: * double imaginary coordinate of upper left ! 72: * double real coordinate of lower right ! 73: * double imaginary coordinate lower rightft ! 74: * long (loop + 1) counters for histogram values ! 75: */ ! 76: ! 77: ! 78: ! 79: ! 80: #include <stdio.h> ! 81: #include <doscalls.h> ! 82: ! 83: int mandinter (); ! 84: ! 85: #define FALSE 0 ! 86: #define TRUE ~FALSE ! 87: ! 88: #define MAXREAL 2000 /* maximum number of points in line */ ! 89: #define MAXLOOP 1000 /* maximum number of iterations */ ! 90: ! 91: #define CGA_DEV 0 /* Color Graphics Adapter */ ! 92: #define CGA_COL 350 /* number of display columns for CGA */ ! 93: #define CGA_ROW 200 /* number of display rows for CGA */ ! 94: #define CGA_ASP 12/5 /* aspect ratio (width/height) for CGA */ ! 95: ! 96: #define EGA_DEV 1 /* Extended Graphics Adapter */ ! 97: #define EGA_COL 640 /* number of display columns for EGA */ ! 98: #define EGA_ROW 350 /* number of display rows for EGA */ ! 99: #define EGA_ASP 1.33 /* aspect ratio (width/height) for EGA */ ! 100: ! 101: #define PGA_DEV 2 /* Professional Graphics Adapter */ ! 102: #define PGA_COL 640 /* number of display columns for PGA */ ! 103: #define PGA_ROW 480 /* number of display rows for PGA */ ! 104: #define PGA_ASP 1.0 /* aspect ratio (width/height) for PGA */ ! 105: ! 106: ! 107: struct cmplx { ! 108: double realp; /* real part of number */ ! 109: double imagp; /* imaginary part of number */ ! 110: }; ! 111: ! 112: ! 113: ! 114: char fp287; /* 287 processor status from DOSDEVCONFIG */ ! 115: char pmand[60] = "mandel.cnt"; /* file name for loop counts */ ! 116: FILE *fmand; ! 117: ! 118: double rinc; /* increment in real coordinate */ ! 119: double iinc; /* increment in imaginary coordinate */ ! 120: ! 121: int device = EGA_DEV; /* default device type */ ! 122: int arg_device = -1; /* device type from arguments */ ! 123: int mcount[MAXREAL]; /* array holding interation counters */ ! 124: int rlcount[MAXREAL + 2]; /* run length encoded interation counters */ ! 125: int nreal = EGA_COL; /* number of points on real coordinate */ ! 126: int arg_nreal = 0; /* number real coordinate from arguments */ ! 127: int nimag = EGA_ROW; /* number of points on imaginary coordinate */ ! 128: int arg_nimag = 0; /* number imaginary coordinate from arguments */ ! 129: int loop = 256; /* maximum loop count for each point */ ! 130: int verbose = FALSE; /* display scan line information if true */ ! 131: double aspect = EGA_ASP; /* default screen aspect ratio */ ! 132: double arg_aspect = 0.0; /* aspect from arguments */ ! 133: ! 134: long hist[MAXLOOP + 1] = {0}; /* histogram counters */ ! 135: ! 136: struct cmplx c; /* value of mandelbrot seed */ ! 137: struct cmplx ul; /* coordinates of upper left corner */ ! 138: struct cmplx lr; /* coordinates of lower right corner */ ! 139: ! 140: ! 141: main (argc, argv) ! 142: int argc; ! 143: char **argv; ! 144: { ! 145: int nr; ! 146: int ni; ! 147: int i; ! 148: int temp; ! 149: int *rl; ! 150: long position; ! 151: ! 152: if (DOSDEVCONFIG ((char far *)&fp287, 3, 0) != 0) { ! 153: printf ("Unable to get fp processor presence flag\n"); ! 154: exit (1); ! 155: } ! 156: if (fp287 != 1) { ! 157: printf ("There is not a 287 fp processor present\n"); ! 158: exit (1); ! 159: } ! 160: nextarg (argc, argv); ! 161: if ((fmand = fopen (pmand, "wb")) == NULL) { ! 162: printf ("Unable to open count file %s\n", pmand); ! 163: exit (3); ! 164: } ! 165: if (ul.realp == lr.realp && ul.imagp == lr.imagp) { ! 166: printf ("%15.13lf+%15.13lfi, %15.13lf+%15.13lfi\n",ul.realp,ul.imagp,lr.realp,lr.imagp); ! 167: printf ("Upper left real = lower right real\n"); ! 168: exit (3); ! 169: } ! 170: ! 171: /* reset nreal, nimag, aspect from command line device type */ ! 172: ! 173: switch (arg_device) { ! 174: case CGA_DEV: ! 175: nreal = CGA_COL; ! 176: nimag = CGA_ROW; ! 177: aspect = CGA_ASP; ! 178: break; ! 179: ! 180: case EGA_DEV: ! 181: nreal = EGA_COL; ! 182: nimag = EGA_ROW; ! 183: aspect = EGA_ASP; ! 184: break; ! 185: ! 186: case PGA_DEV: ! 187: nreal = PGA_COL; ! 188: nimag = PGA_ROW; ! 189: aspect = PGA_ASP; ! 190: break; ! 191: } ! 192: ! 193: /* reset individual parameters */ ! 194: ! 195: if (arg_nreal != 0) ! 196: nreal = arg_nreal; ! 197: if (arg_nimag != 0) ! 198: nimag = arg_nimag; ! 199: if (arg_aspect != 0) ! 200: aspect = arg_aspect; ! 201: ! 202: /* compute the step increments for the specifed aspect */ ! 203: ! 204: rinc = (lr.realp - ul.realp) / (double)nreal; ! 205: iinc = rinc * aspect; ! 206: ! 207: lr.imagp = ul.imagp - iinc * nimag; ! 208: ! 209: fwrite ((char *)&nreal, sizeof (int), 1, fmand); ! 210: fwrite ((char *)&nimag, sizeof (int), 1, fmand); ! 211: fwrite ((char *)&loop, sizeof (int), 1, fmand); ! 212: fwrite ((char *)&ul, sizeof (ul), 1, fmand); ! 213: fwrite ((char *)&lr, sizeof (lr), 1, fmand); ! 214: fwrite ((char *)&rinc, sizeof (rinc), 1, fmand); ! 215: fwrite ((char *)&iinc, sizeof (iinc), 1, fmand); ! 216: fwrite ((char *)&aspect, sizeof (aspect), 1, fmand); ! 217: position = ftell (fmand); ! 218: fwrite ((char *)hist, sizeof (long), loop + 1, fmand); ! 219: ! 220: c.imagp = ul.imagp; ! 221: for (ni = 0; ni < nimag; ni++) { ! 222: c.realp = ul.realp; ! 223: if (verbose) ! 224: printf ("%4d, %15.13lf + %15.13lfi", ni, c.realp, c.imagp); ! 225: manditer (c.realp, c.imagp, loop, nreal, mcount, rinc); ! 226: for (nr = 0; nr < nreal; nr++) { ! 227: i = mcount[nr]; ! 228: hist[i]++; ! 229: } ! 230: ! 231: /* run length encode counts for this scan line */ ! 232: ! 233: temp = *mcount; ! 234: nr = 1; ! 235: rl = rlcount + 1; ! 236: i = -1; ! 237: for (; nr < nreal; nr++) { ! 238: i++; ! 239: if (mcount[nr] != temp) { ! 240: /* process change in value */ ! 241: if (i != 0) ! 242: /* output count of duplicate values */ ! 243: *rl++ = -(i + 1); ! 244: /* output value */ ! 245: *rl++ = temp; ! 246: /* reset compression values */ ! 247: temp = mcount[nr]; ! 248: i = -1; ! 249: } ! 250: } ! 251: if (i != -1) { ! 252: if (i != 0) ! 253: /* output count of duplicate values */ ! 254: *rl++ = -(i + 2); ! 255: /* output value */ ! 256: *rl++ = temp; ! 257: } ! 258: *rlcount = rl - rlcount -1; ! 259: if (verbose) ! 260: printf ("%4d\n", *rlcount); ! 261: if (fwrite ((char *)rlcount, sizeof (int), *rlcount + 1, fmand) != ! 262: *rlcount + 1) { ! 263: printf ("error writing count file %s\n", pmand); ! 264: exit (4); ! 265: } ! 266: c.imagp -= iinc; ! 267: } ! 268: fseek (fmand, position, 0); ! 269: if (fwrite ((char *)hist, sizeof (long), loop + 1, fmand) != loop + 1) { ! 270: printf ("error writing histogram to file %s\n", pmand); ! 271: exit (4); ! 272: } ! 273: } ! 274: ! 275: ! 276: ! 277: /** nextarg - process arguments ! 278: * ! 279: */ ! 280: ! 281: ! 282: nextarg (argc, argv) ! 283: int argc; ! 284: char **argv; ! 285: { ! 286: ! 287: argv++; ! 288: while ((argc-- > 0) && (**argv == '-')) { ! 289: switch (*(*argv+1)) { ! 290: case 'a': ! 291: /* specify aspect ratio */ ! 292: argv++; ! 293: if ((argc < 1) || ! 294: (sscanf (*argv++, "%lf", &arg_aspect) != 1)) { ! 295: printf ("Error specifing aspect\n"); ! 296: exit (1); ! 297: } ! 298: argc--; ! 299: break; ! 300: ! 301: case 'c': ! 302: /* specify number of columns and limit to maximum value */ ! 303: argv++; ! 304: if ((argc < 1) || ! 305: (sscanf (*argv++, " %d", &arg_nreal) != 1)) { ! 306: printf ("Error specifying number of real points\n"); ! 307: exit (1); ! 308: } ! 309: argc--; ! 310: if (arg_nreal > MAXREAL) { ! 311: arg_nreal = MAXREAL; ! 312: printf ("Number of columns limited to %d\n", MAXREAL); ! 313: } ! 314: break; ! 315: ! 316: case 'd': ! 317: /* specify default device paramters */ ! 318: argv++; ! 319: if (strcmp (*argv, "CGA") == 0) ! 320: arg_device = CGA_DEV; ! 321: else if (strcmp (*argv, "EGA") == 0) ! 322: arg_device = EGA_DEV; ! 323: else if (strcmp (*argv, "PGA") == 0) ! 324: arg_device = PGA_DEV; ! 325: else { ! 326: printf ("Error specifing device\n"); ! 327: exit (1); ! 328: } ! 329: argv++; ! 330: argc--; ! 331: break; ! 332: ! 333: case 'f': ! 334: /* specify output file name */ ! 335: argv++; ! 336: /* set file name */ ! 337: strcpy (pmand, *argv); ! 338: strcat (pmand, ".cnt"); ! 339: break; ! 340: ! 341: case 'i': ! 342: /* specify iteration count and limit to maximum */ ! 343: argv++; ! 344: if ((argc < 1) || ! 345: (sscanf (*argv++, " %d", &loop) != 1)) { ! 346: printf ("Error specifying iteration limit\n"); ! 347: exit (1); ! 348: } ! 349: argc--; ! 350: if (loop > MAXLOOP) { ! 351: loop = MAXREAL; ! 352: printf ("Iteration count limited to %d\n", MAXLOOP); ! 353: } ! 354: break; ! 355: ! 356: case 'l': ! 357: /* specify lower right corner as c+di */ ! 358: argv++; ! 359: if ((argc < 1) || (sscanf (*argv++, "%lf%lfi", ! 360: &lr.realp, &lr.imagp) != 2)) { ! 361: printf ("Error specifying lower right\n"); ! 362: exit (1); ! 363: } ! 364: argc--; ! 365: break; ! 366: ! 367: ! 368: case 'r': ! 369: /* specify number of rows */ ! 370: argv++; ! 371: if ((argc < 1) || ! 372: (sscanf (*argv++, " %d", &arg_nimag) != 1)) { ! 373: printf ("Error specifying number of imaginary points\n"); ! 374: exit (1); ! 375: } ! 376: argc--; ! 377: break; ! 378: ! 379: case 'u': ! 380: /* specify upper right corner as a+bi */ ! 381: argv++; ! 382: if ((argc < 1) || (sscanf (*argv++, "%lf%lfi", ! 383: &ul.realp, &ul.imagp) != 2)) { ! 384: printf ("Error specifying upper left\n"); ! 385: exit (1); ! 386: } ! 387: argc--; ! 388: break; ! 389: ! 390: case 'v': ! 391: /* specify verbose output */ ! 392: argv++; ! 393: verbose = TRUE; ! 394: break; ! 395: ! 396: default: ! 397: printf ("Unknown argument %s\n", *argv); ! 398: exit (1); ! 399: ! 400: } ! 401: } ! 402: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.