/* $Id$ * stern.c 25.12.2006 * stern.c 07.02.2004 * STERN.C 11.07.2003 * STERN.CPP 11.02.2000 * STERN.BAS 29.04.1996 */ #include #include #include #include #include #include struct point { int x, y, z; }; struct line { struct point a, b; }; int Calc3D(struct point *, float, float, int *, int *); void DrawObject(int, struct line *, int); #define Usleep 10000 #define Width 400 #define Height 400 #define Pi M_PI #define NMELM(p) (sizeof(p) / sizeof((p)[0])) #define SECOND #if defined(FIRST) #define D 500 struct line world[] = { {{ 50, 50, 50}, {-50, 50, 50}}, {{ 50,-50, 50}, {-50,-50, 50}}, {{ 50, 50,-50}, {-50, 50,-50}}, {{ 50,-50,-50}, {-50,-50,-50}}, {{ 50, 50, 50}, { 50,-50, 50}}, {{-50, 50, 50}, {-50,-50, 50}}, {{ 50, 50,-50}, { 50,-50,-50}}, {{-50, 50,-50}, {-50,-50,-50}}, {{ 50, 50, 50}, { 50, 50,-50}}, {{ 50,-50, 50}, { 50,-50,-50}}, {{-50,-50, 50}, {-50,-50,-50}}, {{-50, 50, 50}, {-50, 50,-50}} }; #elif defined(SECOND) #define D 200 struct line world[] = { {{-60, 40, 20}, {-20, 40, 20}}, {{-20, 40, 20}, {-20, 0, 20}}, {{-20, 0, 20}, { 60, 0, 20}}, {{ 60, 0, 20}, { 60,-40, 20}}, {{ 60,-40, 20}, {-60,-40, 20}}, {{-60,-40, 20}, {-60, 40, 20}}, {{-60, 40,-20}, {-20, 40,-20}}, {{-20, 40,-20}, {-20, 0,-20}}, {{-20, 0,-20}, { 60, 0,-20}}, {{ 60, 0,-20}, { 60,-40,-20}}, {{ 60,-40,-20}, {-60,-40,-20}}, {{-60,-40,-20}, {-60, 40,-20}}, {{-60, 40, 20}, {-60, 40,-20}}, {{-20, 40, 20}, {-20, 40,-20}}, {{-20, 0, 20}, {-20, 0,-20}}, {{ 60, 0, 20}, { 60, 0,-20}}, {{ 60,-40, 20}, { 60,-40,-20}}, {{-60,-40, 20}, {-60,-40,-20}} }; #else #define D 300 struct line world[] = { {{ 90, 0, 0}, { 10, 10, 10}}, {{ 90, 0, 0}, { 10, 10,-10}}, {{ 90, 0, 0}, { 10,-10,-10}}, {{ 90, 0, 0}, { 10,-10, 10}}, {{-90, 0, 0}, {-10, 10, 10}}, {{-90, 0, 0}, {-10, 10,-10}}, {{-90, 0, 0}, {-10,-10,-10}}, {{-90, 0, 0}, {-10,-10, 10}}, {{ 0, 90, 0}, { 10, 10, 10}}, {{ 0, 90, 0}, {-10, 10, 10}}, {{ 0, 90, 0}, {-10, 10,-10}}, {{ 0, 90, 0}, { 10, 10,-10}}, {{ 0,-90, 0}, { 10,-10, 10}}, {{ 0,-90, 0}, {-10,-10, 10}}, {{ 0,-90, 0}, {-10,-10,-10}}, {{ 0,-90, 0}, { 10,-10,-10}}, {{ 0, 0, 90}, { 10, 10, 10}}, {{ 0, 0, 90}, { 10,-10, 10}}, {{ 0, 0, 90}, {-10,-10, 10}}, {{ 0, 0, 90}, {-10, 10, 10}}, {{ 0, 0,-90}, { 10, 10,-10}}, {{ 0, 0,-90}, { 10,-10,-10}}, {{ 0, 0,-90}, {-10,-10,-10}}, {{ 0, 0,-90}, {-10, 10,-10}}, {{ 10, 10, 10}, {-10, 10, 10}}, {{ 10,-10, 10}, {-10,-10, 10}}, {{ 10, 10,-10}, {-10, 10,-10}}, {{ 10,-10,-10}, {-10,-10,-10}}, {{ 10, 10, 10}, { 10,-10, 10}}, {{-10, 10, 10}, {-10,-10, 10}}, {{ 10, 10,-10}, { 10,-10,-10}}, {{-10, 10,-10}, {-10,-10,-10}}, {{ 10, 10, 10}, { 10, 10,-10}}, {{ 10,-10, 10}, { 10,-10,-10}}, {{-10,-10, 10}, {-10,-10,-10}}, {{-10, 10, 10}, {-10, 10,-10}} }; #endif /* XGCValues values; */ Display *display; Window win; Pixmap pix; GC wingc, pixgc; int black, white; int die = 0; int main(int argc, char **argv) { int screen; int r = 0; int pause = 0; Atom delwin; display = XOpenDisplay(argc == 2 ? argv[1] : NULL); screen = DefaultScreen(display); black = BlackPixel(display, screen); white = WhitePixel(display, screen); win = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, Width, Height, 0, black, white); XStoreName(display, win, "Stern $Revision$"); delwin = XInternAtom(display, "WM_DELETE_WINDOW", 0); XSetWMProtocols(display, win, &delwin, 1); wingc = XCreateGC(display, win, 0, NULL); XSetGraphicsExposures(display, wingc, False); XSetBackground(display, wingc, white); pix = XCreatePixmap(display, win, Width, Height, 1); pixgc = XCreateGC(display, pix, 0, NULL); XSetLineAttributes(display, pixgc, 2, LineSolid, CapButt, JoinBevel); XSelectInput(display, win, KeyPressMask); XMapWindow(display, win); while (!die) { if (XPending(display)) { XEvent event; XNextEvent(display, &event); switch (event.type) { case KeyPress: switch (XLookupKeysym(&event.xkey, 0)) { case XK_space: pause = !pause; break; case XK_Escape: case XK_q: XCloseDisplay(display); exit(0); } case ClientMessage: die = *event.xclient.data.l == delwin; break; default: break; } } if (!pause) { r %= 360; DrawObject(++r, world, NMELM(world)); } usleep(Usleep); } XFreePixmap(display, pix); XDestroyWindow(display, win); XCloseDisplay(display); return 0; } void DrawObject(int r, struct line *p, int nelem) { float R, Sr, Cr; int i; int x1, y1, x2, y2; R = Pi * r / 180; Sr = sin(R); Cr = cos(R); XSetForeground(display, pixgc, 0); XFillRectangle(display, pix, pixgc, 0, 0, Width, Height); XSetForeground(display, pixgc, 1); for(i = 0; i < nelem; ++i) { Calc3D(&p[i].a, Sr, Cr, &x1, &y1); Calc3D(&p[i].b, Sr, Cr, &x2, &y2); XDrawLine(display, pix, pixgc, x1, y1, x2, y2); } XCopyPlane(display, pix, win, wingc, 0, 0, Width, Height, 0, 0, 1); } int Calc3D(struct point *p, float Sr, float Cr, int *x, int *y) { float X, Y, Z, Xa, Ya, Za; X = p->x; Y = p->y; Z = p->z; Ya = Y * Cr + Z * Sr; Za = Z * Cr - Y * Sr; Xa = X * Cr + Za * Sr; Z = Za * Cr - X * Sr; X = Xa * Cr + Ya * Sr; Y = Ya * Cr - Xa * Sr; *x = 2 * X * (Y + D) / D + Width / 2; *y = 2 * Z * (Y + D) / D + Height / 2; return Y < 0; }