Annotation of researchv9/X11/src/X.V11R1/demos/ico/ico.c, revision 1.1.1.1

1.1       root        1: /* $Header: ico.c,v 1.1 87/09/11 08:23:25 toddb Exp $ */
                      2: /***********************************************************
                      3: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      4: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      5: 
                      6:                         All Rights Reserved
                      7: 
                      8: Permission to use, copy, modify, and distribute this software and its 
                      9: documentation for any purpose and without fee is hereby granted, 
                     10: provided that the above copyright notice appear in all copies and that
                     11: both that copyright notice and this permission notice appear in 
                     12: supporting documentation, and that the names of Digital or MIT not be
                     13: used in advertising or publicity pertaining to distribution of the
                     14: software without specific, written prior permission.  
                     15: 
                     16: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     17: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     18: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     19: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     20: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     21: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     22: SOFTWARE.
                     23: 
                     24: ******************************************************************/
                     25: /******************************************************************************
                     26:  * Description
                     27:  *     Display a wire-frame rotating icosahedron, with hidden lines removed
                     28:  *
                     29:  * Arguments:
                     30:  *     -r              display on root window instead of creating a new one
                     31:  *     =wxh+x+y        X geometry for new window (default 600x600 centered)
                     32:  *     host:display    X display on which to run
                     33:  *****************************************************************************/
                     34: 
                     35: 
                     36: 
                     37: #include <X11/Xlib.h>
                     38: #include <X11/Xatom.h>
                     39: #include <X11/Xutil.h>
                     40: #include <stdio.h>
                     41: 
                     42: 
                     43: 
                     44: typedef struct
                     45:        {
                     46:        double x, y, z;
                     47:        } Point3D;
                     48: 
                     49: typedef double Transform3D[4][4];
                     50: 
                     51: 
                     52: 
                     53: extern GC XCreateGC();
                     54: extern long time();
                     55: extern long random();
                     56: 
                     57: Display *dpy;
                     58: 
                     59: /******************************************************************************
                     60:  * Description
                     61:  *     Main routine.  Process command-line arguments, then bounce a bounding
                     62:  *     box inside the window.  Call DrawIco() to redraw the icosahedron.
                     63:  *****************************************************************************/
                     64: 
                     65: main(argc, argv)
                     66: int argc;
                     67: char **argv;
                     68:        {
                     69:        char *display = NULL;
                     70:        char *geom = NULL;
                     71:        int useRoot = 0;
                     72:        int fg, bg;
                     73:        int invert = 0;
                     74:        int dash = 0;
                     75: 
                     76:        Window win;
                     77:        int winX, winY, winW, winH;
                     78:        XSetWindowAttributes xswa;
                     79: 
                     80:        GC gc;
                     81: 
                     82:        int icoX, icoY;
                     83:        int icoDeltaX, icoDeltaY;
                     84:        int icoW, icoH;
                     85: 
                     86:        XEvent xev;
                     87:        XGCValues xgcv;
                     88: 
                     89:        /* Process arguments: */
                     90: 
                     91:        while (*++argv)
                     92:                {
                     93:                if (**argv == '=') 
                     94:                        geom = *argv;
                     95:                else if (index(*argv, ':'))
                     96:                        display = *argv;
                     97:                else if (!strcmp(*argv, "-r"))
                     98:                        useRoot = 1;
                     99:                else if (!strcmp (*argv, "-d"))
                    100:                        dash = atoi(*++argv);
                    101:                else if (!strcmp(*argv, "-i"))
                    102:                        invert = 1;
                    103:                }
                    104: 
                    105: 
                    106:        if (!(dpy= XOpenDisplay(display)))
                    107:                {
                    108:                perror("Cannot open display\n");
                    109:                exit(-1);
                    110:                }
                    111: 
                    112:        if (invert)
                    113:                {
                    114:                fg = BlackPixel(dpy, DefaultScreen(dpy));
                    115:                bg = WhitePixel(dpy, DefaultScreen(dpy));
                    116:                }
                    117:        else
                    118:                {
                    119:                fg = WhitePixel(dpy, DefaultScreen(dpy));
                    120:                bg = BlackPixel(dpy, DefaultScreen(dpy));
                    121:                }
                    122: 
                    123:        /* Set up window parameters, create and map window if necessary: */
                    124: 
                    125:        if (useRoot)
                    126:                {
                    127:                win = DefaultRootWindow(dpy);
                    128:                winX = 0;
                    129:                winY = 0;
                    130:                winW = DisplayWidth(dpy, DefaultScreen(dpy));
                    131:                winH = DisplayHeight(dpy, DefaultScreen(dpy));
                    132:                }
                    133:        else
                    134:                {
                    135:                winW = 600;
                    136:                winH = 600;
                    137:                winX = (DisplayWidth(dpy, DefaultScreen(dpy)) - winW) >> 1;
                    138:                winY = (DisplayHeight(dpy, DefaultScreen(dpy)) - winH) >> 1;
                    139:                if (geom) 
                    140:                        XParseGeometry(geom, &winX, &winY, &winW, &winH);
                    141: 
                    142:                xswa.event_mask = 0;
                    143:                xswa.background_pixel = bg;
                    144:                xswa.border_pixel = fg;
                    145:                win = XCreateWindow(dpy, DefaultRootWindow(dpy), 
                    146:                    winX, winY, winW, winH, 0, 
                    147:                    DefaultDepth(dpy, DefaultScreen(dpy)), 
                    148:                    InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
                    149:                    CWEventMask | CWBackPixel | CWBorderPixel, &xswa);
                    150:                XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, 
                    151:                                PropModeReplace, "Ico", 3);
                    152:                XMapWindow(dpy, win);
                    153:                }
                    154: 
                    155: 
                    156:        /* Set up a graphics context: */
                    157: 
                    158:        gc = XCreateGC(dpy, win, 0, NULL);
                    159:        XSetForeground(dpy, gc, fg);
                    160:        XSetBackground(dpy, gc, bg);
                    161: 
                    162:        if (dash)
                    163:                {
                    164:                xgcv.line_style = LineDoubleDash;
                    165:                xgcv.dashes = dash;
                    166:                XChangeGC(dpy, gc, GCLineStyle | GCDashList, &xgcv);
                    167:                }
                    168: 
                    169:        /* Get the initial position, size, and speed of the bounding-box: */
                    170: 
                    171:        icoW = icoH = 150;
                    172:        srandom((int) time(0) % 231);
                    173:        icoX = ((winW - icoW) * (random() & 0xFF)) >> 8;
                    174:        icoY = ((winH - icoH) * (random() & 0xFF)) >> 8;
                    175:        icoDeltaX = 13;
                    176:        icoDeltaY = 9;
                    177: 
                    178: 
                    179:        /* Bounce the box in the window: */
                    180: 
                    181:        for (;;)
                    182:                {
                    183:                int prevX;
                    184:                int prevY;
                    185: 
                    186:                if (XPending(dpy))
                    187:                        XNextEvent(dpy, &xev);
                    188: 
                    189:                prevX = icoX;
                    190:                prevY = icoY;
                    191: 
                    192:                icoX += icoDeltaX;
                    193:                if (icoX < 0 || icoX + icoW > winW)
                    194:                        {
                    195:                        icoX -= (icoDeltaX << 1);
                    196:                        icoDeltaX = - icoDeltaX;
                    197:                        }
                    198:                icoY += icoDeltaY;
                    199:                if (icoY < 0 || icoY + icoH > winH)
                    200:                        {
                    201:                        icoY -= (icoDeltaY << 1);
                    202:                        icoDeltaY = - icoDeltaY;
                    203:                        }
                    204: 
                    205:                drawIco(win, gc, icoX, icoY, icoW, icoH, prevX, prevY);
                    206:                }
                    207:        }
                    208: 
                    209: 
                    210: 
                    211: /******************************************************************************
                    212:  * Description
                    213:  *     Undraw previous icosahedron (by erasing its bounding box).
                    214:  *     Rotate and draw the new icosahedron.
                    215:  *
                    216:  * Input
                    217:  *     win             window on which to draw
                    218:  *     gc              X11 graphics context to be used for drawing
                    219:  *     icoX, icoY      position of upper left of bounding-box
                    220:  *     icoW, icoH      size of bounding-box
                    221:  *     prevX, prevY    position of previous bounding-box
                    222:  *****************************************************************************/
                    223: 
                    224: drawIco(win, gc, icoX, icoY, icoW, icoH, prevX, prevY)
                    225: Window win;
                    226: GC gc;
                    227: int icoX, icoY, icoW, icoH;
                    228: int prevX, prevY;
                    229:        {
                    230:        static int initialized = 0;
                    231:        static Point3D v[] =    /* icosahedron vertices */
                    232:                {
                    233:                { 0.00000000,  0.00000000, -0.95105650},
                    234:                { 0.00000000,  0.85065080, -0.42532537},
                    235:                { 0.80901698,  0.26286556, -0.42532537},
                    236:                { 0.50000000, -0.68819095, -0.42532537},
                    237:                {-0.50000000, -0.68819095, -0.42532537},
                    238:                {-0.80901698,  0.26286556, -0.42532537},
                    239:                { 0.50000000,  0.68819095,  0.42532537},
                    240:                { 0.80901698, -0.26286556,  0.42532537},
                    241:                { 0.00000000, -0.85065080,  0.42532537},
                    242:                {-0.80901698, -0.26286556,  0.42532537},
                    243:                {-0.50000000,  0.68819095,  0.42532537},
                    244:                { 0.00000000,  0.00000000,  0.95105650}
                    245:                };
                    246:        static int f[] =        /* icosahedron faces (indices in v) */
                    247:                {
                    248:                 0,  2,  1,
                    249:                 0,  3,  2,
                    250:                 0,  4,  3,
                    251:                 0,  5,  4,
                    252:                 0,  1,  5,
                    253:                 1,  6, 10,
                    254:                 1,  2,  6,
                    255:                 2,  7,  6,
                    256:                 2,  3,  7,
                    257:                 3,  8,  7,
                    258:                 3,  4,  8,
                    259:                 4,  9,  8,
                    260:                 4,  5,  9,
                    261:                 5, 10,  9,
                    262:                 5,  1, 10,
                    263:                10,  6, 11,
                    264:                 6,  7, 11,
                    265:                 7,  8, 11,
                    266:                 8,  9, 11,
                    267:                 9, 10, 11
                    268:                };
                    269: #      define NV (sizeof(v) / sizeof(v[0]))
                    270: #      define NF (sizeof(f) / (3 * sizeof(f[0])))
                    271: 
                    272:        static Transform3D xform;
                    273:        static Point3D xv[2][NV];
                    274:        static int buffer;
                    275:        register int p0;
                    276:        register int p1;
                    277:        register int p2;
                    278:        register XPoint *pv2;
                    279:        XSegment *pe;
                    280:        char drawn[NV][NV];
                    281:        register Point3D *pxv;
                    282:        static double wo2, ho2;
                    283:        XPoint v2[NV];
                    284:        XSegment edges[30];
                    285:        register int i;
                    286:        register int *pf;
                    287: 
                    288: 
                    289:        /* Set up points, transforms, etc.:  */
                    290: 
                    291:        if (!initialized)       
                    292:                {
                    293:                Transform3D r1;
                    294:                Transform3D r2;
                    295: 
                    296:                FormatRotateMat('x', 5 * 3.1416 / 180.0, r1);
                    297:                FormatRotateMat('y', 5 * 3.1416 / 180.0, r2);
                    298:                ConcatMat(r1, r2, xform);
                    299: 
                    300:                bcopy((char *) v, (char *) xv[0], NV * sizeof(Point3D));
                    301:                buffer = 0;
                    302: 
                    303:                wo2 = icoW / 2.0;
                    304:                ho2 = icoH / 2.0;
                    305: 
                    306:                initialized = 1;
                    307:                }
                    308: 
                    309: 
                    310:        /* Switch double-buffer and rotate vertices: */
                    311: 
                    312:        buffer = !buffer;
                    313:        PartialNonHomTransform(NV, xform, xv[!buffer], xv[buffer]);
                    314: 
                    315: 
                    316:        /* Convert 3D coordinates to 2D window coordinates: */
                    317: 
                    318:        pxv = xv[buffer];
                    319:        pv2 = v2;
                    320:        for (i = NV - 1; i >= 0; --i)
                    321:                {
                    322:                pv2->x = (int) ((pxv->x + 1.0) * wo2) + icoX;
                    323:                pv2->y = (int) ((pxv->y + 1.0) * ho2) + icoY;
                    324:                ++pxv;
                    325:                ++pv2;
                    326:                }
                    327: 
                    328: 
                    329:        /* Accumulate edges to be drawn, eliminating duplicates for speed: */
                    330: 
                    331:        pxv = xv[buffer];
                    332:        pv2 = v2;
                    333:        pf = f;
                    334:        pe = edges;
                    335:        bzero(drawn, sizeof(drawn));
                    336:        for (i = NF - 1; i >= 0; --i)
                    337:                {
                    338:                p0 = *pf++;
                    339:                p1 = *pf++;
                    340:                p2 = *pf++;
                    341: 
                    342:                /* If facet faces away from viewer, don't consider it: */
                    343:                if (pxv[p0].z + pxv[p1].z + pxv[p2].z < 0.0)
                    344:                        continue;
                    345: 
                    346:                if (!drawn[p0][p1])
                    347:                        {
                    348:                        drawn[p0][p1] = 1;
                    349:                        drawn[p1][p0] = 1;
                    350:                        pe->x1 = pv2[p0].x;
                    351:                        pe->y1 = pv2[p0].y;
                    352:                        pe->x2 = pv2[p1].x;
                    353:                        pe->y2 = pv2[p1].y;
                    354:                        ++pe;
                    355:                        }
                    356:                if (!drawn[p1][p2])
                    357:                        {
                    358:                        drawn[p1][p2] = 1;
                    359:                        drawn[p2][p1] = 1;
                    360:                        pe->x1 = pv2[p1].x;
                    361:                        pe->y1 = pv2[p1].y;
                    362:                        pe->x2 = pv2[p2].x;
                    363:                        pe->y2 = pv2[p2].y;
                    364:                        ++pe;
                    365:                        }
                    366:                if (!drawn[p2][p0])
                    367:                        {
                    368:                        drawn[p2][p0] = 1;
                    369:                        drawn[p0][p2] = 1;
                    370:                        pe->x1 = pv2[p2].x;
                    371:                        pe->y1 = pv2[p2].y;
                    372:                        pe->x2 = pv2[p0].x;
                    373:                        pe->y2 = pv2[p0].y;
                    374:                        ++pe;
                    375:                        }
                    376:                }
                    377: 
                    378: 
                    379:        /* Erase previous, draw current icosahedrons; sync for smoothness. */
                    380: 
                    381:        XClearArea(dpy, win, prevX, prevY, icoW + 1, icoH + 1, 0);
                    382:        XDrawSegments(dpy, win, gc, edges, pe - edges);
                    383:        XSync(dpy, 0);
                    384:        }
                    385: 
                    386: 
                    387: 
                    388: /******************************************************************************
                    389:  * Description
                    390:  *     Concatenate two 4-by-4 transformation matrices.
                    391:  *
                    392:  * Input
                    393:  *     l               multiplicand (left operand)
                    394:  *     r               multiplier (right operand)
                    395:  *
                    396:  * Output
                    397:  *     *m              Result matrix
                    398:  *****************************************************************************/
                    399: 
                    400: ConcatMat(l, r, m)
                    401: register Transform3D l;
                    402: register Transform3D r;
                    403: register Transform3D m;
                    404:        {
                    405:        register int i;
                    406:        register int j;
                    407:        register int k;
                    408: 
                    409:        for (i = 0; i < 4; ++i)
                    410:                for (j = 0; j < 4; ++j)
                    411:                        m[i][j] = l[i][0] * r[0][j]
                    412:                            + l[i][1] * r[1][j]
                    413:                            + l[i][2] * r[2][j]
                    414:                            + l[i][3] * r[3][j];
                    415:        }
                    416: 
                    417: 
                    418: 
                    419: /******************************************************************************
                    420:  * Description
                    421:  *     Format a matrix that will perform a rotation transformation
                    422:  *     about the specified axis.  The rotation angle is measured
                    423:  *     counterclockwise about the specified axis when looking
                    424:  *     at the origin from the positive axis.
                    425:  *
                    426:  * Input
                    427:  *     axis            Axis ('x', 'y', 'z') about which to perform rotation
                    428:  *     angle           Angle (in radians) of rotation
                    429:  *     A               Pointer to rotation matrix
                    430:  *
                    431:  * Output
                    432:  *     *m              Formatted rotation matrix
                    433:  *****************************************************************************/
                    434: 
                    435: FormatRotateMat(axis, angle, m)
                    436: char axis;
                    437: double angle;
                    438: register Transform3D m;
                    439:        {
                    440:        double s, c;
                    441:        double sin(), cos();
                    442: 
                    443:        IdentMat(m);
                    444: 
                    445:        s = sin(angle);
                    446:        c = cos(angle);
                    447: 
                    448:        switch(axis)
                    449:                {
                    450:                case 'x':
                    451:                        m[1][1] = m[2][2] = c;
                    452:                        m[1][2] = s;
                    453:                        m[2][1] = -s;
                    454:                        break;
                    455:                case 'y':
                    456:                        m[0][0] = m[2][2] = c;
                    457:                        m[2][0] = s;
                    458:                        m[0][2] = -s;
                    459:                        break;
                    460:                case 'z':
                    461:                        m[0][0] = m[1][1] = c;
                    462:                        m[0][1] = s;
                    463:                        m[1][0] = -s;
                    464:                        break;
                    465:                }
                    466:        }
                    467: 
                    468: 
                    469: 
                    470: /******************************************************************************
                    471:  * Description
                    472:  *     Format a 4x4 identity matrix.
                    473:  *
                    474:  * Output
                    475:  *     *m              Formatted identity matrix
                    476:  *****************************************************************************/
                    477: 
                    478: IdentMat(m)
                    479: register Transform3D m;
                    480:        {
                    481:        register int i;
                    482:        register int j;
                    483: 
                    484:        for (i = 3; i >= 0; --i)
                    485:                {
                    486:                for (j = 3; j >= 0; --j)
                    487:                        m[i][j] = 0.0;
                    488:                m[i][i] = 1.0;
                    489:                }
                    490:        }
                    491: 
                    492: 
                    493: 
                    494: /******************************************************************************
                    495:  * Description
                    496:  *     Perform a partial transform on non-homogeneous points.
                    497:  *     Given an array of non-homogeneous (3-coordinate) input points,
                    498:  *     this routine multiplies them by the 3-by-3 upper left submatrix
                    499:  *     of a standard 4-by-4 transform matrix.  The resulting non-homogeneous
                    500:  *     points are returned.
                    501:  *
                    502:  * Input
                    503:  *     n               number of points to transform
                    504:  *     m               4-by-4 transform matrix
                    505:  *     in              array of non-homogeneous input points
                    506:  *
                    507:  * Output
                    508:  *     *out            array of transformed non-homogeneous output points
                    509:  *****************************************************************************/
                    510: 
                    511: PartialNonHomTransform(n, m, in, out)
                    512: int n;
                    513: register Transform3D m;
                    514: register Point3D *in;
                    515: register Point3D *out;
                    516:        {
                    517:        for (; n > 0; --n, ++in, ++out)
                    518:                {
                    519:                out->x = in->x * m[0][0] + in->y * m[1][0] + in->z * m[2][0];
                    520:                out->y = in->x * m[0][1] + in->y * m[1][1] + in->z * m[2][1];
                    521:                out->z = in->x * m[0][2] + in->y * m[1][2] + in->z * m[2][2];
                    522:                }
                    523:        }

unix.superglobalmegacorp.com

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