/* $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; GC gc; int main(int argc, char **argv) { XEvent event; int screen; int black, white; int r = 0; int pause = 0; 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$"); XSelectInput(display, win, KeyPressMask); gc = XCreateGC(display, win, 0, NULL); XSetForeground(display, gc, black); XSetBackground(display, gc, white); XSetLineAttributes(display, gc, 2, LineSolid, CapButt, JoinBevel); XSetFillStyle(display, gc, FillSolid); XMapWindow(display, win); for (;;) { if (XPending(display)) { 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); } default: break; } } if (!pause) { XClearWindow(display, win); if (r >= 360) r = 0; DrawObject(++r, world, NMELM(world)); } usleep(Usleep); } 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); for(i = 0; i < nelem; ++i) { Calc3D(&p[i].a, Sr, Cr, &x1, &y1); Calc3D(&p[i].b, Sr, Cr, &x2, &y2); XDrawLine(display, win, gc, x1, y1, x2, y2); } } 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; }