v11i011: xwave, Part01/01
Paul Riddle
paulr at umbc5.umbc.edu
Wed Jan 30 10:47:29 AEST 1991
Submitted-by: paulr at umbc5.umbc.edu (Paul Riddle)
Posting-number: Volume 11, Issue 11
Archive-name: xwave/part01
This is a short demo program that plots a perspective projection of a
3-d mesh and waves it around in real time. We thought it might make an
interesting submission, so we decided to clean it up a little bit and
send it to you (now that the semester's over, we have time to do things
like that :-)
Anyhow, enjoy...
Paul Riddle (paulr at umbc3.umbc.edu)
Mike Friedman (mikef at umbc3.umbc.edu)
-------------------cut--------------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Imakefile Makefile README patchlevel.h xwave.1 xwave.c
# Wrapped by paulr at elnath on Wed Jan 2 15:31:48 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(105 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X DEPLIBS = $(DEPXLIB)
XLOCAL_LIBRARIES = $(XLIB)
X SYS_LIBRARIES = -lm
X
XSimpleProgramTarget(xwave)
END_OF_FILE
if test 105 -ne `wc -c <'Imakefile'`; then
echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(172 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC = cc
XCFLAGS = -O
XLDFLAGS = -s
XSRCS = xwave.c
XOBJS = xwave.o
XLIBS = -lm -lX11
X
Xxwave: $(OBJS)
X $(CC) $(LDFLAGS) -o xwave $(OBJS) $(LIBS)
X
X.o: $*.c
X $(CC) $(CFLAGS) -c $@
END_OF_FILE
if test 172 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1152 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xxwave is a simple demo program that plots a perspective projection
Xof a 3-d mesh surface and then "waves" it in real time. We have
Xtested it under Ultrix 4.0, HP-UX 7.0, and SunOS 4.0.3. It works
Xon both X11R4 and X11R3 servers.
X
XThe program works best on a risc workstation; if you have something
Xslower, try making the MAXROWS and MAXCOLS constants smaller numbers.
X15 by 15 works pretty well on slower machines.
X
XWhile the program is running, you can use the mouse to move the
Xplot around, and the left and right mouse buttons to zoom it in and
Xout.
X
XUsers with color displays can specify the -3d option. Be sure to
Xhave your 3-d glasses ready (if you don't have any, you can make
Xthem out of red and blue cellophane :-). The effect is pretty
Xinteresting.
X
XThere are a few more options; these are all described in the man
Xpage. Inquiries, bug reports, etc. should be directed to
Xpaulr at umbc3.umbc.edu.
X
XXwave may be freely copied and redistributed in any form, providing
Xthe authors' names stay with the source code. Let us know if you
Xlike it, improve it, etc.
X
XAuthors:
XMike Friedman (mikef at umbc3.umbc.edu)
XPaul Riddle (paulr at umbc3.umbc.edu)
END_OF_FILE
if test 1152 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 1
END_OF_FILE
if test 21 -ne `wc -c <'patchlevel.h'`; then
echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'xwave.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xwave.1'\"
else
echo shar: Extracting \"'xwave.1'\" \(721 characters\)
sed "s/^X//" >'xwave.1' <<'END_OF_FILE'
X.TH xwave 1
X.SH Name
Xxwave \- A real-time perspective mesh demo for X
X.SH Syntax
X.B xwave
X[
X.I -root
X]
X[
X.I -3d
X]
X.SH Description
Xxwave plots a perspective projection of a 3-d mesh and waves it.
XAll calculations are done in real time. Double buffering is
Xsimulated using a background pixmap.
X
XWhile the wave is being displayed, you can move it around using
Xthe mouse, and zoom it in and out using the left and right mouse
Xbuttons.
X.SH Options
X.IP \-root
XPlot the wave in the root window.
X.IP \-3d
XPlot separate projections in red and blue. Make sure you have your
X3-d glasses handy. You also need a color display (obviously).
X.SH Authors
XPaul Riddle (paulr at umbc3.umbc.edu)
X.br
XMike Friedman (mikef at umbc3.umbc.edu)
X
END_OF_FILE
if test 721 -ne `wc -c <'xwave.1'`; then
echo shar: \"'xwave.1'\" unpacked with wrong size!
fi
# end of 'xwave.1'
fi
if test -f 'xwave.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xwave.c'\"
else
echo shar: Extracting \"'xwave.c'\" \(9527 characters\)
sed "s/^X//" >'xwave.c' <<'END_OF_FILE'
X/******************************************************************************
X** xwave - A 3-d perspective mesh for X
X**
X** Authors:
X** Mike Friedman (mikef at umbc3.umbc.edu)
X** Paul Riddle (paulr at umbc3.umbc.edu)
X**
X** University of Maryland, Baltimore County
X******************************************************************************/
X
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xos.h>
X#include <stdio.h>
X#include <math.h>
X
X#include "patchlevel.h"
X
X#define STARTX 20
X#define STARTY 50
X#define MAXROWS 18
X#define MAXCOLS 25
X#define GENS 2
X#define TWOPI10 400 /* 62*5 */
X#define TWOPI 6.283
X#define WIDTH 400
X#define HEIGHT 500
X
X#define ROOT 0x1
X#define THREED 0x2
X
Xint FD = 25, PD = 15;
X
XColormap cmap;
XXColor red, blue;
X
XGC gc;
XWindow win;
XDisplay *dpy;
Xint screen, scrnWidth = WIDTH, scrnHeight = HEIGHT;
XPixmap buffer;
X
Xunsigned short flags = 0;
X
X/******************************************************************************
X** module: initColor
X**
X** This loads the red and blue colors into the color map.
X******************************************************************************/
X
Xvoid initColor ()
X{
X cmap = DefaultColormap (dpy, screen);
X red.red = 40000;
X red.blue = 0;
X red.green = 0;
X blue.red = 0;
X blue.blue = 60000;
X blue.green = 0;
X
X if (!(XAllocColor (dpy, cmap, &red)) ||
X !(XAllocColor (dpy, cmap, &blue))) {
X (void) fprintf (stderr, "Error: Cannot allocate colors\n");
X exit (1);
X }
X}
X
X/******************************************************************************
X** module: initialize
X**
X** This sets the window up.
X******************************************************************************/
X
Xvoid initialize ()
X{
X if (!(dpy = XOpenDisplay (""))) {
X (void) fprintf (stderr, "Error: Can't open display\n");
X exit (1);
X }
X screen = DefaultScreen (dpy);
X if (flags & ROOT) {
X win = DefaultRootWindow (dpy);
X scrnWidth = DisplayWidth (dpy, screen);
X scrnHeight = DisplayHeight (dpy, screen);
X }
X else {
X win = XCreateSimpleWindow (dpy, DefaultRootWindow (dpy),
X 0, 0, scrnWidth, scrnHeight, 1,
X WhitePixel (dpy, screen),
X BlackPixel (dpy, screen));
X XSelectInput (dpy, win, ExposureMask | StructureNotifyMask);
X XStoreName (dpy, win, "XWave");
X XMapWindow (dpy, win);
X }
X gc = XCreateGC (dpy, win, 0L, (XGCValues *) 0);
X if (flags & THREED)
X initColor ();
X buffer = XCreatePixmap (dpy, DefaultRootWindow (dpy), scrnWidth,
X scrnHeight, DefaultDepth (dpy, screen));
X}
X
X/******************************************************************************
X** module: setupSinTable
X**
X** This routine initializes the sine table. The table is accessed during
X** computation to speed things up somewhat.
X******************************************************************************/
X
Xvoid setupSinTable (sinTab)
X double *sinTab;
X{
X int i;
X double t = 0.0;
X
X for (i = 0; i < TWOPI10; i++, t += TWOPI / TWOPI10)
X sinTab[i] = sin (t);
X}
X
X/*
X * Perspective projections of points in 3-space to screen coordinates.
X * These are implemented as macros to avoid function call overhead without
X * (well, almost without..) sacrificing readability of the code.
X */
X
X#define xrpers(x,y,z) ((int) (PD - FD * (PD - (x)) / (FD - (z)) + 100))
X#define yrpers(x,y,z) ((int) (FD * (y) / (FD - (z)) + 150))
X#define xlpers(x,y,z) ((int) (-PD - FD * (-PD - (x)) / (FD - (z)) + 100))
X#define ylpers(x,y,z) ((int) (FD * (y) / (FD - (z)) + 150))
X
X/*
X * Line plotting routines. Again, these are all macros.
X */
X
X#define plotLineRed(x0,y0,z0,x1,y1,z1) \
X XSetForeground (dpy, gc, red.pixel); \
X XDrawLine (dpy, buffer, gc, \
X xlpers ((float) (x0), (float) (y0), (float) (z0)), \
X ylpers ((float) (x0), (float) (y0), (float) (z0)), \
X xlpers ((float) (x1), (float) (y1), (float) (z1)), \
X ylpers ((float) (x1), (float) (y1), (float) (z1)))
X
X#define plotLineBlue(x0,y0,z0,x1,y1,z1) \
X XSetForeground (dpy, gc, blue.pixel); \
X XDrawLine (dpy, buffer, gc, \
X xrpers ((float) (x0), (float) (y0), (float) (z0)), \
X yrpers ((float) (x0), (float) (y0), (float) (z0)), \
X xrpers ((float) (x1), (float) (y1), (float) (z1)), \
X yrpers ((float) (x1), (float) (y1), (float) (z1)))
X
X#define plotLine(x0,y0,z0,x1,y1,z1) \
X if (flags & THREED) { \
X plotLineRed((x0),(y0),(z0),(x1),(y1),(z1)); \
X plotLineBlue((x0),(y0),(z0),(x1),(y1),(z1)); \
X } else \
X XDrawLine (dpy, buffer, gc, \
X xlpers ((float) (x0), (float) (y0), (float) (z0)), \
X ylpers ((float) (x0), (float) (y0), (float) (z0)), \
X xlpers ((float) (x1), (float) (y1), (float) (z1)), \
X ylpers ((float) (x1), (float) (y1), (float) (z1)))
X
Xmain (argc, argv)
X int argc;
X char *argv[];
X{
X double sinTab[TWOPI10];
X register int t, gap = 10;
X int r, c, px, py, junk, kb;
X int amplitude1 = 150, amplitude2 = 100, cur = 0, next = 1, inc1 = -1,
X inc2 = -1;
X int Generation[MAXROWS][MAXCOLS][GENS];
X Window junk_win;
X
X /*
X * Check args and set appropriate program flags
X */
X while (++argv, --argc) {
X if (!strcmp (*argv, "-root"))
X flags |= ROOT;
X else if (!strcmp (*argv, "-3d"))
X flags |= THREED;
X else {
X (void) fprintf (stderr, "Usage: xwave [-root] [-3d]\n");
X exit (1);
X }
X }
X
X /*
X * Zero out the generation matrix
X */
X for (r = 0; r < MAXROWS; r++)
X for (c = 0; c < MAXCOLS; c++)
X Generation[r][c][0] = Generation[r][c][1] = 0;
X
X /*
X * Set up the window and the sine table
X */
X initialize ();
X setupSinTable (sinTab);
X
X /*
X * Grab an expose event from the server, then we can get started
X */
X if (!(flags & ROOT)) {
X for (;;) {
X XEvent event;
X XNextEvent(dpy, &event);
X if (event.type == Expose) break;
X }
X XWarpPointer (dpy, None, win, 0, 0, 0, 0, scrnWidth / 2,
X scrnHeight / 2);
X }
X
X /*
X * Finally, go into an infinite loop of computing and plotting generations
X */
X for (;;)
X for (t = 0;t < TWOPI10; t++) {
X
X /*
X * Handle resizes. When a resize happens, we need to re-allocate
X * the background pixmap. Note that the bigger the window, the
X * larger the area that needs to get copied, and therefore the
X * slower the program gets.
X */
X if (QLength (dpy)) {
X XEvent event;
X XNextEvent (dpy, &event);
X switch (event.type) {
X case ConfigureNotify:
X if (event.xconfigure.width != scrnWidth ||
X event.xconfigure.height != scrnHeight) {
X XFreePixmap (dpy, buffer);
X scrnWidth = event.xconfigure.width;
X scrnHeight = event.xconfigure.height;
X buffer = XCreatePixmap (dpy, DefaultRootWindow (dpy),
X scrnWidth, scrnHeight,
X DefaultDepth (dpy, screen));
X }
X default:
X break;
X }
X }
X XQueryPointer (dpy, win, &junk_win, &junk_win, &junk, &junk,
X &px, &py, &kb);
X px -= 275;
X py -= 350;
X
X /*
X * Give the user something to do :-)
X */
X if ((kb & Button1Mask) && gap > 10) gap--;
X if ((kb & Button3Mask) && gap < 50) gap++;
X
X /*
X * Load some of the cells
X */
X Generation[1][2][cur]=(int)(amplitude1*sinTab[(30*t)%TWOPI10]);
X Generation[2][4][cur]=(int)(amplitude2*sinTab[(25*t)%TWOPI10]);
X Generation[1][6][cur]=(int)(amplitude1*sinTab[19*(10+t)%TWOPI10]);
X Generation[2][8][cur]=(int)(amplitude2*sinTab[(20*t)%TWOPI10]);
X Generation[15][8][cur]=(int)(amplitude2*sinTab[(5*t)%TWOPI10]);
X Generation[7][10][cur]=(int)(amplitude2*sinTab[(30*t)%TWOPI10]);
X Generation[9][14][cur]=(int)(amplitude2*sinTab[(20*t)%TWOPI10]);
X Generation[12][16][cur]=(int)((amplitude2+50)*sinTab[(3*t)%TWOPI10]);
X Generation[7][3][cur]=(int)(amplitude2*sinTab[(40*t)%TWOPI10]);
X
X /*
X * Increment and/or decrement our amplitudes
X */
X if (amplitude2 == 0)
X inc2 = 5;
X else if (amplitude2 == 350)
X inc2 = -1;
X amplitude2 += inc2;
X if (amplitude1 == 0)
X inc1 = 5;
X else if (amplitude1 == 200)
X inc1 = -1;
X amplitude1 += inc1;
X
X /*
X * Interpolate the values of all the other cells in the matrix
X */
X for (r = 1; r < MAXROWS - 1; r++)
X for (c = 1; c < MAXCOLS - 1; c++)
X Generation[r][c][next] =
X (int) (0.25 * (Generation[r - 1][c][cur]
X + Generation[r][c - 1][cur]
X + Generation[r][c + 1][cur]
X + Generation[r + 1][c][cur]));
X
X /*
X * Plot the new generation in our background pixmap
X */
X for (r = 1; r < MAXROWS - 1; r++) {
X for (c = 0; c < MAXCOLS - 1; c++) {
X int xCoord, yCoord;
X xCoord = gap * c + STARTX;
X yCoord = Generation[r][c][next] + gap * r + STARTY;
X
X plotLine (xCoord + px, yCoord + py, r,
X gap * (c + 1) + STARTX + px,
X Generation[r][c + 1][next] +
X gap * r + STARTY + py, r);
X plotLine (xCoord + px, yCoord + py, r, xCoord + px,
X Generation[r + 1][c][next] +
X gap * (r + 1) + STARTY + py, r + 1);
X }
X }
X cur ^= 1;
X next ^= 1;
X
X /*
X * Swap the background buffer and the window so the new generation
X * shows up on the window.
X */
X XCopyArea (dpy, buffer, win, gc, 0, 0, scrnWidth, scrnHeight, 0, 0);
X XSetForeground (dpy, gc, BlackPixel (dpy, screen));
X XFillRectangle (dpy, buffer, gc, 0, 0, scrnWidth, scrnHeight);
X XSetForeground (dpy, gc, WhitePixel (dpy, screen));
X }
X}
END_OF_FILE
if test 9527 -ne `wc -c <'xwave.c'`; then
echo shar: \"'xwave.c'\" unpacked with wrong size!
fi
# end of 'xwave.c'
fi
echo shar: End of shell archive.
exit 0
--
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list