Annotation of os2sdk/demos/apps/mandel/mandel.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.