X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fgalaxy.c;h=08d870bb6e2a3b312dc748041ecab880465aa73e;hp=ed44d8c2a3cfa213ec20e783a94aeb0adcac0705;hb=14627f4038ada5d11456f3770090f3c39740d70f;hpb=93f25dc6827112d98b8b855ea85c8f5eb8123086 diff --git a/hacks/galaxy.c b/hacks/galaxy.c index ed44d8c2..08d870bb 100644 --- a/hacks/galaxy.c +++ b/hacks/galaxy.c @@ -1,8 +1,8 @@ /* -*- Mode: C; tab-width: 4 -*- */ /* galaxy --- spinning galaxies */ - +/* #include*/ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)galaxy.c 4.04 97/07/28 xlockmore"; +static const char sccsid[] = "@(#)galaxy.c 4.04 97/07/28 xlockmore"; #endif /* Originally done by Uli Siegmund on Amiga @@ -24,53 +24,55 @@ static const char sccsid[] = "@(#)galaxy.c 4.04 97/07/28 xlockmore"; * other special, indirect and consequential damages. * * Revision History: + * 26-Aug-00: robert.nagtegaal@phil.uu.nl and roland@tschai.demon.nl: + * various improvements * 10-May-97: jwz@jwz.org: turned into a standalone program. * 18-Apr-97: Memory leak fixed by Tom Schmidt * 07-Apr-97: Modified by Dave Mitchell - * random star sizes - * colors change depending on velocity - * 23-Oct-94: Modified by David Bagley + * 23-Oct-94: Modified by David Bagley + * random star sizes + * colors change depending on velocity * 10-Oct-94: Add colors by Hubert Feyer * 30-Sep-94: Initial port by Hubert Feyer * 09-Mar-94: VMS can generate a random number 0.0 which results in a * division by zero, corrected by Jouk Jansen - * + * */ #ifdef STANDALONE -# define PROGCLASS "Galaxy" -# define HACK_INIT init_galaxy -# define HACK_DRAW draw_galaxy -# define galaxy_opts xlockmore_opts -# define DEFAULTS "*delay: 100 \n" \ - "*count: -5 \n" \ - "*cycles: 250 \n" \ - "*size: -3 \n" \ - "*ncolors: 64 \n" +# define PROGCLASS "Galaxy" +# define HACK_INIT init_galaxy +# define HACK_DRAW draw_galaxy +# define galaxy_opts xlockmore_opts +# define DEFAULTS "*delay: 100 \n" \ + "*count: -5 \n" \ + "*cycles: 250 \n" \ + "*size: -3 \n" \ + "*ncolors: 64 \n" # define UNIFORM_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ +# include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ +# include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ static Bool tracks; -#define DEF_TRACKS "False" +#define DEF_TRACKS "True" static XrmOptionDescRec opts[] = { - {"-tracks", ".galaxy.tracks", XrmoptionNoArg, (caddr_t) "on"}, - {"+tracks", ".galaxy.tracks", XrmoptionNoArg, (caddr_t) "off"} + {"-tracks", ".galaxy.tracks", XrmoptionNoArg, (caddr_t) "on"}, + {"+tracks", ".galaxy.tracks", XrmoptionNoArg, (caddr_t) "off"} }; static argtype vars[] = { - {(caddr_t *) & tracks, "tracks", "Tracks", DEF_TRACKS, t_Bool} + {(caddr_t *) & tracks, "tracks", "Tracks", DEF_TRACKS, t_Bool} }; static OptionStruct desc[] = { - {"-/+tracks", "turn on/off star tracks"} + {"-/+tracks", "turn on/off star tracks"} }; ModeSpecOpt galaxy_opts = { 2, opts, 1, vars, desc }; @@ -79,19 +81,19 @@ ModeSpecOpt galaxy_opts = { 2, opts, 1, vars, desc }; #define FLOATRAND ((double) LRAND() / ((double) MAXRAND)) #if 0 -#define WRAP 1 /* Warp around edges */ -#define BOUNCE 1 /* Bounce from borders */ +#define WRAP 1 /* Warp around edges */ +#define BOUNCE 1 /* Bounce from borders */ #endif #define MINSIZE 1 -#define MINGALAXIES 1 -#define MAX_STARS 300 +#define MINGALAXIES 2 +#define MAX_STARS 3000 #define MAX_IDELTAT 50 /* These come originally from the Cluster-version */ -#define DEFAULT_GALAXIES 2 +#define DEFAULT_GALAXIES 3 #define DEFAULT_STARS 1000 #define DEFAULT_HITITERATIONS 7500 -#define DEFAULT_IDELTAT 200 /* 0.02 */ +#define DEFAULT_IDELTAT 200 /* 0.02 */ #define EPSILON 0.00000001 #define sqrt_EPSILON 0.0001 @@ -99,57 +101,46 @@ ModeSpecOpt galaxy_opts = { 2, opts, 1, vars, desc }; #define DELTAT (MAX_IDELTAT * 0.0001) #define GALAXYRANGESIZE 0.1 -#define GALAXYMINSIZE 0.1 +#define GALAXYMINSIZE 0.15 #define QCONS 0.001 -/*- - * The following is enabled, it does not look that good for some. - * (But it looks great for me.) Maybe velocities should be measured - * relative to their galaxy-centers instead of absolute. - */ -#if 0 -#undef NO_VELOCITY_COLORING */ /* different colors for different speeds */ -#endif -#define COLORBASE 8 +#define COLORBASE 16 /* Colors for stars start here */ -#define COLORSTEP (NUMCOLORS/COLORBASE) /* 8 colors per galaxy */ +#define COLORSTEP (NUMCOLORS/COLORBASE) /* NUMCOLORS / COLORBASE colors +per galaxy */ -#define drawStar(x,y,size) if(size<=1) XDrawPoint(display,window,gc,x,y);\ - else XFillArc(display,window,gc,x,y,size,size,0,23040) typedef struct { - double pos[3], vel[3]; - int px, py; - int color; - int size; + double pos[3], vel[3]; } Star; + typedef struct { - int mass; - int nstars; - Star *stars; - double pos[3], vel[3]; - int galcol; + int mass; + int nstars; + Star *stars; + XPoint *oldpoints; + XPoint *newpoints; + double pos[3], vel[3]; + int galcol; } Galaxy; typedef struct { - struct { - int left; /* x minimum */ - int right; /* x maximum */ - int top; /* y minimum */ - int bottom; /* y maximum */ - } clip; - double mat[3][3]; /* Movement of stars(?) */ - double scale; /* Scale */ - int midx; /* Middle of screen, x */ - int midy; /* Middle of screen, y */ - double size; /* */ - double diff[3]; /* */ - Galaxy *galaxies; /* the Whole Universe */ - int ngalaxies; /* # galaxies */ - int f_hititerations; /* # iterations before restart */ - int step; /* */ + double mat[3][3]; /* Movement of stars(?) */ + double scale; /* Scale */ + int midx; /* Middle of screen, x */ + int midy; /* Middle of screen, y */ + double size; /* */ + double diff[3]; /* */ + Galaxy *galaxies; /* the Whole Universe */ + int ngalaxies; /* # galaxies */ + int f_hititerations; /* # iterations before restart */ + int step; /* */ + double rot_y; /* rotation of eye around center of universe, around +y-axis*/ + double rot_x; /* rotation of eye around center of universe, around +x-axis */ } unistruct; static unistruct *universes = NULL; @@ -157,313 +148,288 @@ static unistruct *universes = NULL; static void free_galaxies(unistruct * gp) { - if (gp->galaxies != NULL) { - int i; - - for (i = 0; i < gp->ngalaxies; i++) { - Galaxy *gt = &gp->galaxies[i]; - - if (gt->stars != NULL) - (void) free((void *) gt->stars); - } - (void) free((void *) gp->galaxies); - gp->galaxies = NULL; - } + if (gp->galaxies != NULL) { + int i; + + for (i = 0; i < gp->ngalaxies; i++) { + Galaxy *gt = &gp->galaxies[i]; + + if (gt->stars != NULL) + (void) free((void *) gt->stars); + if (gt->oldpoints != NULL) + (void) free((void *) gt->oldpoints); + if (gt->newpoints != NULL) + (void) free((void *) gt->newpoints); + } + (void) free((void *) gp->galaxies); + gp->galaxies = NULL; + } } static void startover(ModeInfo * mi) { - unistruct *gp = &universes[MI_SCREEN(mi)]; - int size = MI_SIZE(mi); - int i, j; /* more tmp */ - double w1, w2; /* more tmp */ - double d, v, w, h; /* yet more tmp */ - - gp->step = 0; - - if (MI_BATCHCOUNT(mi) < -MINGALAXIES) - free_galaxies(gp); - gp->ngalaxies = MI_BATCHCOUNT(mi); - if (gp->ngalaxies < -MINGALAXIES) - gp->ngalaxies = NRAND(-gp->ngalaxies - MINGALAXIES + 1) + MINGALAXIES; - else if (gp->ngalaxies < MINGALAXIES) - gp->ngalaxies = MINGALAXIES; - if (gp->galaxies == NULL) - gp->galaxies = (Galaxy *) calloc(gp->ngalaxies, sizeof (Galaxy)); - - for (i = 0; i < gp->ngalaxies; ++i) { - Galaxy *gt = &gp->galaxies[i]; - double sinw1, sinw2, cosw1, cosw2; - - gt->galcol = NRAND(COLORBASE - 2); - if (gt->galcol > 1) - gt->galcol += 2; /* Mult 8; 16..31 no green stars */ - /* Galaxies still may have some green stars but are not all green. */ - - if (gt->stars != NULL) { - (void) free((void *) gt->stars); - gt->stars = NULL; - } - gt->nstars = (NRAND(MAX_STARS / 2)) + MAX_STARS / 2; - gt->stars = (Star *) malloc(gt->nstars * sizeof (Star)); - w1 = 2.0 * M_PI * FLOATRAND; - w2 = 2.0 * M_PI * FLOATRAND; - sinw1 = SINF(w1); - sinw2 = SINF(w2); - cosw1 = COSF(w1); - cosw2 = COSF(w2); - - gp->mat[0][0] = cosw2; - gp->mat[0][1] = -sinw1 * sinw2; - gp->mat[0][2] = cosw1 * sinw2; - gp->mat[1][0] = 0.0; - gp->mat[1][1] = cosw1; - gp->mat[1][2] = sinw1; - gp->mat[2][0] = -sinw2; - gp->mat[2][1] = -sinw1 * cosw2; - gp->mat[2][2] = cosw1 * cosw2; - - gt->vel[0] = FLOATRAND * 2.0 - 1.0; - gt->vel[1] = FLOATRAND * 2.0 - 1.0; - gt->vel[2] = FLOATRAND * 2.0 - 1.0; - gt->pos[0] = -gt->vel[0] * DELTAT * - gp->f_hititerations + FLOATRAND - 0.5; - gt->pos[1] = -gt->vel[1] * DELTAT * - gp->f_hititerations + FLOATRAND - 0.5; - gt->pos[2] = -gt->vel[2] * DELTAT * - gp->f_hititerations + FLOATRAND - 0.5; - - gt->mass = (int) (FLOATRAND * 1000.0) + 1; - - gp->size = GALAXYRANGESIZE * FLOATRAND + GALAXYMINSIZE; - - for (j = 0; j < gt->nstars; ++j) { - Star *st = >->stars[j]; - double sinw, cosw; - - w = 2.0 * M_PI * FLOATRAND; - sinw = SINF(w); - cosw = COSF(w); - d = FLOATRAND * gp->size; - h = FLOATRAND * exp(-2.0 * (d / gp->size)) / 5.0 * gp->size; - if (FLOATRAND < 0.5) - h = -h; - st->pos[0] = gp->mat[0][0] * d * cosw + gp->mat[1][0] * d * sinw + - gp->mat[2][0] * h + gt->pos[0]; - st->pos[1] = gp->mat[0][1] * d * cosw + gp->mat[1][1] * d * sinw + - gp->mat[2][1] * h + gt->pos[1]; - st->pos[2] = gp->mat[0][2] * d * cosw + gp->mat[1][2] * d * sinw + - gp->mat[2][2] * h + gt->pos[2]; - - v = sqrt(gt->mass * QCONS / sqrt(d * d + h * h)); - st->vel[0] = -gp->mat[0][0] * v * sinw + gp->mat[1][0] * v * cosw + - gt->vel[0]; - st->vel[1] = -gp->mat[0][1] * v * sinw + gp->mat[1][1] * v * cosw + - gt->vel[1]; - st->vel[2] = -gp->mat[0][2] * v * sinw + gp->mat[1][2] * v * cosw + - gt->vel[2]; - - st->vel[0] *= DELTAT; - st->vel[1] *= DELTAT; - st->vel[2] *= DELTAT; - - st->px = 0; - st->py = 0; - - if (size < -MINSIZE) - st->size = NRAND(-size - MINSIZE + 1) + MINSIZE; - else if (size < MINSIZE) - st->size = MINSIZE; - else - st->size = size; - } - } - - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); + unistruct *gp = &universes[MI_SCREEN(mi)]; + int i, j; /* more tmp */ + double w1, w2; /* more tmp */ + double d, v, w, h; /* yet more tmp */ + + gp->step = 0; + gp->rot_y = 0; + gp->rot_x = 0; + + if (MI_BATCHCOUNT(mi) < -MINGALAXIES) + free_galaxies(gp); + gp->ngalaxies = MI_BATCHCOUNT(mi); + if (gp->ngalaxies < -MINGALAXIES) + gp->ngalaxies = NRAND(-gp->ngalaxies - MINGALAXIES + 1) + MINGALAXIES; + + else if (gp->ngalaxies < MINGALAXIES) + gp->ngalaxies = MINGALAXIES; + if (gp->galaxies == NULL) + gp->galaxies = (Galaxy *) calloc(gp->ngalaxies, sizeof (Galaxy)); + + for (i = 0; i < gp->ngalaxies; ++i) { + Galaxy *gt = &gp->galaxies[i]; + double sinw1, sinw2, cosw1, cosw2; + + gt->galcol = NRAND(COLORBASE - 2); + if (gt->galcol > 1) + gt->galcol += 2; /* Mult 8; 16..31 no green stars */ + /* Galaxies still may have some green stars but are not all green. */ + + if (gt->stars != NULL) { + (void) free((void *) gt->stars); + gt->stars = NULL; + } + gt->nstars = (NRAND(MAX_STARS / 2)) + MAX_STARS / 2; + gt->stars = (Star *) malloc(gt->nstars * sizeof (Star)); + gt->oldpoints = (XPoint *) malloc(gt->nstars * sizeof (XPoint)); + gt->newpoints = (XPoint *) malloc(gt->nstars * sizeof (XPoint)); + + w1 = 2.0 * M_PI * FLOATRAND; + w2 = 2.0 * M_PI * FLOATRAND; + sinw1 = SINF(w1); + sinw2 = SINF(w2); + cosw1 = COSF(w1); + cosw2 = COSF(w2); + + gp->mat[0][0] = cosw2; + gp->mat[0][1] = -sinw1 * sinw2; + gp->mat[0][2] = cosw1 * sinw2; + gp->mat[1][0] = 0.0; + gp->mat[1][1] = cosw1; + gp->mat[1][2] = sinw1; + gp->mat[2][0] = -sinw2; + gp->mat[2][1] = -sinw1 * cosw2; + gp->mat[2][2] = cosw1 * cosw2; + + gt->vel[0] = FLOATRAND * 2.0 - 1.0; + gt->vel[1] = FLOATRAND * 2.0 - 1.0; + gt->vel[2] = FLOATRAND * 2.0 - 1.0; + gt->pos[0] = -gt->vel[0] * DELTAT * gp->f_hititerations + FLOATRAND - +0.5; + gt->pos[1] = -gt->vel[1] * DELTAT * gp->f_hititerations + FLOATRAND - +0.5; + gt->pos[2] = -gt->vel[2] * DELTAT * gp->f_hititerations + FLOATRAND - +0.5; + + gt->mass = (int) (FLOATRAND * 1000.0) + 1; + + gp->size = GALAXYRANGESIZE * FLOATRAND + GALAXYMINSIZE; + + for (j = 0; j < gt->nstars; ++j) { + Star *st = >->stars[j]; + XPoint *oldp = >->oldpoints[j]; + XPoint *newp = >->newpoints[j]; + + double sinw, cosw; + + w = 2.0 * M_PI * FLOATRAND; + sinw = SINF(w); + cosw = COSF(w); + d = FLOATRAND * gp->size; + h = FLOATRAND * exp(-2.0 * (d / gp->size)) / 5.0 * gp->size; + if (FLOATRAND < 0.5) + h = -h; + st->pos[0] = gp->mat[0][0] * d * cosw + gp->mat[1][0] * d * sinw + +gp->mat[2][0] * h + gt->pos[0]; + st->pos[1] = gp->mat[0][1] * d * cosw + gp->mat[1][1] * d * sinw + +gp->mat[2][1] * h + gt->pos[1]; + st->pos[2] = gp->mat[0][2] * d * cosw + gp->mat[1][2] * d * sinw + +gp->mat[2][2] * h + gt->pos[2]; + + v = sqrt(gt->mass * QCONS / sqrt(d * d + h * h)); + st->vel[0] = -gp->mat[0][0] * v * sinw + gp->mat[1][0] * v * cosw + +gt->vel[0]; + st->vel[1] = -gp->mat[0][1] * v * sinw + gp->mat[1][1] * v * cosw + +gt->vel[1]; + st->vel[2] = -gp->mat[0][2] * v * sinw + gp->mat[1][2] * v * cosw + +gt->vel[2]; + + st->vel[0] *= DELTAT; + st->vel[1] *= DELTAT; + st->vel[2] *= DELTAT; + + oldp->x = 0; + oldp->y = 0; + newp->x = 0; + newp->y = 0; + } + + } + + XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); #if 0 - (void) printf("ngalaxies=%d, f_hititerations=%d\n", - gp->ngalaxies, gp->f_hititerations); - (void) printf("f_deltat=%g\n", DELTAT); - (void) printf("Screen: "); - (void) printf("%dx%d pixel (%d-%d, %d-%d)\n", - (gp->clip.right - gp->clip.left), (gp->clip.bottom - gp->clip.top), - gp->clip.left, gp->clip.right, gp->clip.top, gp->clip.bottom); + (void) printf("ngalaxies=%d, f_hititerations=%d\n", gp->ngalaxies, +gp->f_hititerations); + (void) printf("f_deltat=%g\n", DELTAT); + (void) printf("Screen: "); #endif /*0 */ } void init_galaxy(ModeInfo * mi) { - unistruct *gp; - - if (universes == NULL) { - if ((universes = (unistruct *) calloc(MI_NUM_SCREENS(mi), - sizeof (unistruct))) == NULL) - return; - } - gp = &universes[MI_SCREEN(mi)]; - - gp->f_hititerations = MI_CYCLES(mi); - - gp->clip.left = 0; - gp->clip.top = 0; - gp->clip.right = MI_WIN_WIDTH(mi); - gp->clip.bottom = MI_WIN_HEIGHT(mi); - - gp->scale = (double) (gp->clip.right + gp->clip.bottom) / 8.0; - gp->midx = gp->clip.right / 2; - gp->midy = gp->clip.bottom / 2; - startover(mi); + unistruct *gp; + + if (universes == NULL) { + if ((universes = (unistruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (unistruct))) == NULL) + return; + } + gp = &universes[MI_SCREEN(mi)]; + + gp->f_hititerations = MI_CYCLES(mi); + + gp->scale = (double) (MI_WIN_WIDTH(mi) + MI_WIN_HEIGHT(mi)) / 8.0; + gp->midx = MI_WIN_WIDTH(mi) / 2; + gp->midy = MI_WIN_HEIGHT(mi) / 2; + startover(mi); } void draw_galaxy(ModeInfo * mi) { - Display *display = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - GC gc = MI_GC(mi); - unistruct *gp = &universes[MI_SCREEN(mi)]; - double d; /* tmp */ - int i, j, k; /* more tmp */ - - for (i = 0; i < gp->ngalaxies; ++i) { - Galaxy *gt = &gp->galaxies[i]; - - for (j = 0; j < gp->galaxies[i].nstars; ++j) { - Star *st = >->stars[j]; - double v0 = st->vel[0]; - double v1 = st->vel[1]; - double v2 = st->vel[2]; - - for (k = 0; k < gp->ngalaxies; ++k) { - Galaxy *gtk = &gp->galaxies[k]; - double d0 = gtk->pos[0] - st->pos[0]; - double d1 = gtk->pos[1] - st->pos[1]; - double d2 = gtk->pos[2] - st->pos[2]; - - d = d0 * d0 + d1 * d1 + d2 * d2; - if (d > EPSILON) - d = gt->mass / (d * sqrt(d)) * DELTAT * DELTAT * QCONS; - else - d = gt->mass / (EPSILON * sqrt_EPSILON) * DELTAT * DELTAT * QCONS; - v0 += d0 * d; - v1 += d1 * d; - v2 += d2 * d; - } - - st->vel[0] = v0; - st->vel[1] = v1; - st->vel[2] = v2; - -#ifndef NO_VELOCITY_COLORING - d = (v0 * v0 + v1 * v1 + v2 * v2) / (3.0 * DELTAT * DELTAT); - if (d > (double) COLORSTEP) - st->color = COLORSTEP * gt->galcol + COLORSTEP - 1; - else - st->color = COLORSTEP * gt->galcol + ((int) d) % COLORSTEP; -#endif - st->pos[0] += v0; - st->pos[1] += v1; - st->pos[2] += v2; - - if (st->px >= gp->clip.left && - st->px <= gp->clip.right - st->size && - st->py >= gp->clip.top && - st->py <= gp->clip.bottom - st->size) { - XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); - drawStar(st->px, st->py, st->size); - } - st->px = (int) (st->pos[0] * gp->scale) + gp->midx; - st->py = (int) (st->pos[1] * gp->scale) + gp->midy; - - -#ifdef WRAP - if (st->px < gp->clip.left) { - (void) printf("wrap l -> r\n"); - st->px = gp->clip.right; - } - if (st->px > gp->clip.right) { - (void) printf("wrap r -> l\n"); - st->px = gp->clip.left; - } - if (st->py > gp->clip.bottom) { - (void) printf("wrap b -> t\n"); - st->py = gp->clip.top; - } - if (st->py < gp->clip.top) { - (void) printf("wrap t -> b\n"); - st->py = gp->clip.bottom; - } -#endif /*WRAP */ - - - if (st->px >= gp->clip.left && - st->px <= gp->clip.right - st->size && - st->py >= gp->clip.top && - st->py <= gp->clip.bottom - st->size) { - if (MI_NPIXELS(mi) > 2) -#ifdef NO_VELOCITY_COLORING - XSetForeground(display, gc, MI_PIXEL(mi, COLORSTEP * gt->galcol)); -#else - XSetForeground(display, gc, MI_PIXEL(mi, st->color)); -#endif - else - XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi)); - if (tracks) - drawStar(st->px + 1, st->py, st->size); - else - drawStar(st->px, st->py, st->size); - } - } - - for (k = i + 1; k < gp->ngalaxies; ++k) { - Galaxy *gtk = &gp->galaxies[k]; - double d0 = gtk->pos[0] - gt->pos[0]; - double d1 = gtk->pos[1] - gt->pos[1]; - double d2 = gtk->pos[2] - gt->pos[2]; - - d = d0 * d0 + d1 * d1 + d2 * d2; - if (d > EPSILON) - d = gt->mass * gt->mass / (d * sqrt(d)) * DELTAT * QCONS; - else - d = gt->mass * gt->mass / (EPSILON * sqrt_EPSILON) * DELTAT * QCONS; - d0 *= d; - d1 *= d; - d2 *= d; - gt->vel[0] += d0 / gt->mass; - gt->vel[1] += d1 / gt->mass; - gt->vel[2] += d2 / gt->mass; - gtk->vel[0] -= d0 / gtk->mass; - gtk->vel[1] -= d1 / gtk->mass; - gtk->vel[2] -= d2 / gtk->mass; - } - gt->pos[0] += gt->vel[0] * DELTAT; - gt->pos[1] += gt->vel[1] * DELTAT; - gt->pos[2] += gt->vel[2] * DELTAT; - } - - gp->step++; - if (gp->step > gp->f_hititerations * 4) - startover(mi); + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + GC gc = MI_GC(mi); + unistruct *gp = &universes[MI_SCREEN(mi)]; + double d, eps, cox, six, cor, sir; /* tmp */ + int i, j, k; /* more tmp */ + XPoint *dummy = NULL; + + gp->rot_y += 0.01; + gp->rot_x += 0.004; + + cox = COSF(gp->rot_y); + six = SINF(gp->rot_y); + cor = COSF(gp->rot_x); + sir = SINF(gp->rot_x); + + eps = 1/(EPSILON * sqrt_EPSILON * DELTAT * DELTAT * QCONS); + + for (i = 0; i < gp->ngalaxies; ++i) { + Galaxy *gt = &gp->galaxies[i]; + + for (j = 0; j < gp->galaxies[i].nstars; ++j) { + Star *st = >->stars[j]; + XPoint *newp = >->newpoints[j]; + double v0 = st->vel[0]; + double v1 = st->vel[1]; + double v2 = st->vel[2]; + + for (k = 0; k < gp->ngalaxies; ++k) { + Galaxy *gtk = &gp->galaxies[k]; + double d0 = gtk->pos[0] - st->pos[0]; + double d1 = gtk->pos[1] - st->pos[1]; + double d2 = gtk->pos[2] - st->pos[2]; + + d = d0 * d0 + d1 * d1 + d2 * d2; + if (d > EPSILON) + d = gt->mass / (d * sqrt(d)) * DELTAT * DELTAT * QCONS; + else + d = gt->mass * eps; + v0 += d0 * d; + v1 += d1 * d; + v2 += d2 * d; + } + + st->vel[0] = v0; + st->vel[1] = v1; + st->vel[2] = v2; + + st->pos[0] += v0; + st->pos[1] += v1; + st->pos[2] += v2; + + newp->x = (short) (((cox * st->pos[0]) - (six * st->pos[2])) * +gp->scale) + gp->midx; + newp->y = (short) (((cor * st->pos[1]) - (sir * ((six * st->pos[0]) + +(cox * st->pos[2])))) * gp->scale) + gp->midy; + + } + + for (k = i + 1; k < gp->ngalaxies; ++k) { + Galaxy *gtk = &gp->galaxies[k]; + double d0 = gtk->pos[0] - gt->pos[0]; + double d1 = gtk->pos[1] - gt->pos[1]; + double d2 = gtk->pos[2] - gt->pos[2]; + + d = d0 * d0 + d1 * d1 + d2 * d2; + if (d > EPSILON) + d = gt->mass * gt->mass / (d * sqrt(d)) * DELTAT * QCONS; + else + d = gt->mass * gt->mass / (EPSILON * sqrt_EPSILON) * DELTAT * QCONS; + + d0 *= d; + d1 *= d; + d2 *= d; + gt->vel[0] += d0 / gt->mass; + gt->vel[1] += d1 / gt->mass; + gt->vel[2] += d2 / gt->mass; + gtk->vel[0] -= d0 / gtk->mass; + gtk->vel[1] -= d1 / gtk->mass; + gtk->vel[2] -= d2 / gtk->mass; + } + + gt->pos[0] += gt->vel[0] * DELTAT; + gt->pos[1] += gt->vel[1] * DELTAT; + gt->pos[2] += gt->vel[2] * DELTAT; + + XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi)); + XDrawPoints(display, window, gc, gt->oldpoints, gt->nstars, +CoordModeOrigin); + XSetForeground(display, gc, MI_PIXEL(mi, COLORSTEP * gt->galcol)); + XDrawPoints(display, window, gc, gt->newpoints, gt->nstars, +CoordModeOrigin); + + dummy = gt->oldpoints; + gt->oldpoints = gt->newpoints; + gt->newpoints = dummy; + } + + gp->step++; + if (gp->step > gp->f_hititerations * 4) + startover(mi); } void release_galaxy(ModeInfo * mi) { - if (universes != NULL) { - int screen; - - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) - free_galaxies(&universes[screen]); - (void) free((void *) universes); - universes = NULL; - } + if (universes != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_galaxies(&universes[screen]); + (void) free((void *) universes); + universes = NULL; + } } void refresh_galaxy(ModeInfo * mi) { - /* Do nothing, it will refresh by itself */ + /* Do nothing, it will refresh by itself */ }