Annotation of researchv9/X11/src/X.V11R1/demos/ico/ico.c, revision 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.