/* Compute average DSF value at the given radius from central vector */ static double eval_DSFsurround(const RBFNODE *rbf, const FVECT outvec, const double rad) { const int ninc = 12; const double phinc = 2.*M_PI/ninc; double sum = 0; int n = 0; FVECT tvec; int i; /* compute initial vector */ if (output_orient*outvec[2] >= 1.-FTINY) { tvec[0] = tvec[2] = 0; tvec[1] = 1; } else { tvec[0] = tvec[1] = 0; tvec[2] = 1; } geodesic(tvec, outvec, tvec, rad, GEOD_RAD); /* average surrounding DSF */ for (i = 0; i < ninc; i++) { if (i) spinvector(tvec, tvec, outvec, phinc); if (tvec[2] > 0 ^ output_orient > 0) continue; sum += eval_rbfrep(rbf, tvec) * COSF(tvec[2]); ++n; } if (n < 2) /* should never happen! */ return(sum); return(sum/(double)n); }
/* Estimate single-lobe radius for DSF at the given outgoing angle */ static double est_DSFrad(const RBFNODE *rbf, const FVECT outvec) { const double rad_epsilon = 0.01; const double DSFtarget = 0.60653066 * eval_rbfrep(rbf,outvec) * COSF(outvec[2]); double inside_rad = rad_epsilon; double outside_rad = 0.5; double DSFinside = eval_DSFsurround(rbf, outvec, inside_rad); double DSFoutside = eval_DSFsurround(rbf, outvec, outside_rad); #define interp_rad inside_rad + (outside_rad-inside_rad) * \ (DSFtarget-DSFinside) / (DSFoutside-DSFinside) /* Newton's method (sort of) */ do { double test_rad = interp_rad; double DSFtest; if ((test_rad >= outside_rad) | (test_rad <= inside_rad)) test_rad = .5*(inside_rad + outside_rad); DSFtest = eval_DSFsurround(rbf, outvec, test_rad); if (DSFtest > DSFtarget) { inside_rad = test_rad; DSFinside = DSFtest; } else { outside_rad = test_rad; DSFoutside = DSFtest; } } while (outside_rad-inside_rad > rad_epsilon); return(.5*(inside_rad + outside_rad)); #undef interp_rad }
/* Conservative estimate of average BSDF value from current DSF's */ static void comp_bsdf_spec(void) { double vmod_sum = 0; double rad_sum = 0; int n = 0; double *cost_list = NULL; double max_cost = 1.; RBFNODE *rbf; FVECT sdv; /* sort by incident altitude */ for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) n++; if (n >= 10) cost_list = (double *)malloc(sizeof(double)*n); if (cost_list == NULL) { bsdf_spec_val = 0; bsdf_spec_rad = 0; return; } n = 0; for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) cost_list[n++] = rbf->invec[2]*input_orient; qsort(cost_list, n, sizeof(double), dbl_cmp); max_cost = cost_list[(n+3)/4]; /* accept 25% nearest grazing */ free(cost_list); n = 0; for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) { double this_rad, cosfact, vest; if (rbf->invec[2]*input_orient > max_cost) continue; sdv[0] = -rbf->invec[0]; sdv[1] = -rbf->invec[1]; sdv[2] = rbf->invec[2]*(2*(input_orient==output_orient) - 1); cosfact = COSF(sdv[2]); this_rad = est_DSFrad(rbf, sdv); vest = eval_rbfrep(rbf, sdv) * cosfact * (2.*M_PI) * this_rad*this_rad; if (vest > rbf->vtotal) /* don't over-estimate energy */ vest = rbf->vtotal; vmod_sum += vest / cosfact; /* remove cosine factor */ rad_sum += this_rad; ++n; } bsdf_spec_rad = rad_sum/(double)n; bsdf_spec_val = vmod_sum/(2.*M_PI*n*bsdf_spec_rad*bsdf_spec_rad); }
static void draw_dots(ModeInfo * mi, int in) { float i, inc; float x, y; spiralstruct *sp = &spirals[MI_SCREEN(mi)]; inc = TWOPI / (float) sp->dots; for (i = 0.0; i < TWOPI; i += inc) { x = sp->traildots[in].hx + COSF(i + sp->traildots[in].ha) * sp->traildots[in].hr; y = sp->traildots[in].hy + SINF(i + sp->traildots[in].ha) * sp->traildots[in].hr; XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), TFX(sp, x), TFY(sp, y)); } }
// input : current spectrum in the form of power *spec and phase *phase, // the last two earlier spectrums are at position // 512 and 1024 of the corresponding Input-Arrays. // Array *vocal, which can mark an FFT_Linie as harmonic // output: current amplitude *amp and unpredictability *cw static void CalcUnpred (PsyModel* m, const int MaxLine, const float* spec, const float* phase, const int* vocal, float* amp0, float* phs0, float* cw ) { int n; float amp; float tmp; #define amp1 ((amp0) + 512) // amp[ 512...1023] contains data of frame-1 #define amp2 ((amp0) + 1024) // amp[1024...1535] contains data of frame-2 #define phs1 ((phs0) + 512) // phs[ 512...1023] contains data of frame-1 #define phs2 ((phs0) + 1024) // phs[1024...1535] contains data of frame-2 for ( n = 0; n < MaxLine; n++ ) { tmp = COSF ((phs0[n] = phase[n]) - 2*phs1[n] + phs2[n]); // copy phase to output-array, predict phase and calculate predictive error amp0[n] = SQRTF (spec[n]); // calculate and set amplitude amp = 2*amp1[n] - amp2[n]; // predict amplitude // calculate unpredictability cw[n] = SQRTF (spec[n] + amp * (amp - 2*amp0[n] * tmp)) / (amp0[n] + FABS(amp)); } // postprocessing of harmonic FFT-lines (*cw is set to CVD_UNPRED) if ( m->CVD_used && vocal != NULL ) { for ( n = 0; n < MAX_CVD_LINE; n++, cw++, vocal++ ) if ( *vocal != 0 && *cw > CVD_UNPRED * 0.01 * *vocal ) *cw = CVD_UNPRED * 0.01 * *vocal; } return; }
ENTRYPOINT void draw_braid(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int num_points = 500; float t_inc; float theta, psi; float t, r_diff; int i, s; float x_1, y_1, x_2, y_2, r1, r2; float color, color_use = 0.0, color_inc; braidtype *braid; if (braids == NULL) return; braid = &braids[MI_SCREEN(mi)]; #ifdef STANDALONE if (braid->eraser) { braid->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), braid->eraser); return; } #endif MI_IS_DRAWN(mi) = True; XSetLineAttributes(display, MI_GC(mi), braid->linewidth, LineSolid, (braid->linewidth <= 3 ? CapButt : CapRound), JoinMiter); theta = (2.0 * M_PI) / (float) (braid->braidlength); t_inc = (2.0 * M_PI) / (float) num_points; color_inc = (float) MI_NPIXELS(mi) * braid->color_direction / (float) num_points; braid->startcolor += SPINRATE * color_inc; if (((int) braid->startcolor) >= MI_NPIXELS(mi)) braid->startcolor = 0.0; r_diff = (braid->max_radius - braid->min_radius) / (float) (braid->nstrands); color = braid->startcolor; psi = 0.0; for (i = 0; i < braid->braidlength; i++) { psi += theta; for (t = 0.0; t < theta; t += t_inc) { #ifdef COLORROUND color += color_inc; if (((int) color) >= MI_NPIXELS(mi)) color = 0.0; color_use = color; #endif for (s = 0; s < braid->nstrands; s++) { if (ABS(braid->braidword[i]) == s) continue; if (ABS(braid->braidword[i]) - 1 == s) { /* crosSINFg */ #ifdef COLORCOMP if (MI_NPIXELS(mi) > 2) { color_use = color + SPINRATE * braid->components[applywordbackto(braid, s, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif #ifdef COLORROUND if (MI_NPIXELS(mi) > 2) { color_use += SPINRATE * color_inc; while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); } #endif r1 = braid->min_radius + r_diff * (float) (s); r2 = braid->min_radius + r_diff * (float) (s + 1); if (braid->braidword[i] > 0 || (FABSF(t - theta / 2.0) > theta / 7.0)) { x_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r2 + 0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r1)) * COSF(t + psi) + braid->center_x; y_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r2 + 0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r1)) * SINF(t + psi) + braid->center_y; x_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r2 + 0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r1)) * COSF(t + t_inc + psi) + braid->center_x; y_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r2 + 0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r1)) * SINF(t + t_inc + psi) + braid->center_y; if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); } #ifdef COLORCOMP if (MI_NPIXELS(mi) > 2) { color_use = color + SPINRATE * braid->components[applywordbackto(braid, s + 1, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif if (braid->braidword[i] < 0 || (FABSF(t - theta / 2.0) > theta / 7.0)) { x_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r1 + 0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r2)) * COSF(t + psi) + braid->center_x; y_1 = ((0.5 * (1.0 + SINF(t / theta * M_PI - M_PI_2)) * r1 + 0.5 * (1.0 + SINF((theta - t) / theta * M_PI - M_PI_2)) * r2)) * SINF(t + psi) + braid->center_y; x_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r1 + 0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r2)) * COSF(t + t_inc + psi) + braid->center_x; y_2 = ((0.5 * (1.0 + SINF((t + t_inc) / theta * M_PI - M_PI_2)) * r1 + 0.5 * (1.0 + SINF((theta - t - t_inc) / theta * M_PI - M_PI_2)) * r2)) * SINF(t + t_inc + psi) + braid->center_y; if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); } } else { /* no crosSINFg */ #ifdef COLORCOMP if (MI_NPIXELS(mi) > 2) { color_use = color + SPINRATE * braid->components[applywordbackto(braid, s, i)] + (psi + t) / 2.0 / M_PI * (float) MI_NPIXELS(mi); while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); while (((int) color_use) < 0) color_use += (float) MI_NPIXELS(mi); } #endif #ifdef COLORROUND if (MI_NPIXELS(mi) > 2) { color_use += SPINRATE * color_inc; while (((int) color_use) >= MI_NPIXELS(mi)) color_use -= (float) MI_NPIXELS(mi); } #endif r1 = braid->min_radius + r_diff * (float) (s); x_1 = r1 * COSF(t + psi) + braid->center_x; y_1 = r1 * SINF(t + psi) + braid->center_y; x_2 = r1 * COSF(t + t_inc + psi) + braid->center_x; y_2 = r1 * SINF(t + t_inc + psi) + braid->center_y; if (MI_NPIXELS(mi) > 2) XSetForeground(display, MI_GC(mi), MI_PIXEL(mi, (int) color_use)); else XSetForeground(display, MI_GC(mi), MI_WHITE_PIXEL(mi)); XDrawLine(display, window, MI_GC(mi), (int) (x_1), (int) (y_1), (int) (x_2), (int) (y_2)); } } } } XSetLineAttributes(display, MI_GC(mi), 1, LineSolid, CapNotLast, JoinRound); if (++braid->age > MI_CYCLES(mi)) { #ifdef STANDALONE braid->eraser = erase_window (MI_DISPLAY(mi), MI_WINDOW(mi), braid->eraser); #endif init_braid(mi); } }
ENTRYPOINT void draw_rotor (ModeInfo * mi) { Display *display = MI_DISPLAY(mi); GC gc = MI_GC(mi); register elem *pelem; int thisx, thisy; int i; int x_1, y_1, x_2, y_2; rotorstruct *rp; if (rotors == NULL) return; rp = &rotors[MI_SCREEN(mi)]; if (rp->elements == NULL) return; MI_IS_DRAWN(mi) = True; if (!rp->iconifiedscreen) { thisx = rp->centerx; thisy = rp->centery; } else { thisx = rp->prevcenterx; thisy = rp->prevcentery; } XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), rp->linewidth, LineSolid, CapButt, JoinMiter); for (i = rp->num, pelem = rp->elements; --i >= 0; pelem++) { if (pelem->radius_drift_max <= pelem->radius_drift_now) { pelem->start_radius = pelem->end_radius; pelem->end_radius = (float) NRAND(40000) / 100.0 - 200.0; pelem->radius_drift_max = (float) NRAND(100000) + 10000.0; pelem->radius_drift_now = 0.0; } if (pelem->ratio_drift_max <= pelem->ratio_drift_now) { pelem->start_ratio = pelem->end_ratio; pelem->end_ratio = (float) NRAND(2000) / 100.0 - 10.0; pelem->ratio_drift_max = (float) NRAND(100000) + 10000.0; pelem->ratio_drift_now = 0.0; } pelem->ratio = pelem->start_ratio + (pelem->end_ratio - pelem->start_ratio) / pelem->ratio_drift_max * pelem->ratio_drift_now; pelem->angle = rp->angle * pelem->ratio; pelem->radius = pelem->start_radius + (pelem->end_radius - pelem->start_radius) / pelem->radius_drift_max * pelem->radius_drift_now; thisx += (int) (COSF(pelem->angle) * pelem->radius); thisy += (int) (SINF(pelem->angle) * pelem->radius); pelem->ratio_drift_now += 1.0; pelem->radius_drift_now += 1.0; } if (rp->firsttime) rp->firsttime = False; else { XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); x_1 = (int) rp->save[rp->rotor].x; y_1 = (int) rp->save[rp->rotor].y; x_2 = (int) rp->save[rp->prev].x; y_2 = (int) rp->save[rp->prev].y; if (rp->iconifiedscreen) { x_1 = x_1 * rp->centerx / rp->prevcenterx; x_2 = x_2 * rp->centerx / rp->prevcenterx; y_1 = y_1 * rp->centery / rp->prevcentery; y_2 = y_2 * rp->centery / rp->prevcentery; } XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); if (MI_NPIXELS(mi) > 2) { XSetForeground(display, gc, MI_PIXEL(mi, rp->pix)); if (++rp->pix >= MI_NPIXELS(mi)) rp->pix = 0; } else XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); x_1 = rp->lastx; y_1 = rp->lasty; x_2 = thisx; y_2 = thisy; if (rp->iconifiedscreen) { x_1 = x_1 * rp->centerx / rp->prevcenterx; x_2 = x_2 * rp->centerx / rp->prevcenterx; y_1 = y_1 * rp->centery / rp->prevcentery; y_2 = y_2 * rp->centery / rp->prevcentery; } XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); } rp->save[rp->rotor].x = rp->lastx = thisx; rp->save[rp->rotor].y = rp->lasty = thisy; ++rp->rotor; rp->rotor %= rp->nsave; ++rp->prev; rp->prev %= rp->nsave; if (rp->forward) { rp->angle += 0.01; if (rp->angle >= MAXANGLE) { rp->angle = MAXANGLE; rp->forward = False; } } else { rp->angle -= 0.1; if (rp->angle <= 0) { rp->angle = 0.0; rp->forward = True; } } if (rp->redrawing) { int j; for (i = 0; i < REDRAWSTEP; i++) { j = (rp->rotor - rp->redrawpos + rp->nsave) % rp->nsave; x_1 = (int) rp->save[j].x; y_1 = (int) rp->save[j].y; x_2 = (int) rp->save[(j - 1 + rp->nsave) % rp->nsave].x; y_2 = (int) rp->save[(j - 1 + rp->nsave) % rp->nsave].y; if (rp->iconifiedscreen) { x_1 = x_1 * rp->centerx / rp->prevcenterx; x_2 = x_2 * rp->centerx / rp->prevcenterx; y_1 = y_1 * rp->centery / rp->prevcentery; y_2 = y_2 * rp->centery / rp->prevcentery; } XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); if (++(rp->redrawpos) >= rp->nsave) { rp->redrawing = 0; break; } } } XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, LineSolid, CapButt, JoinMiter); }
ENTRYPOINT 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, eps, cox, six, cor, sir; /* tmp */ int i, j, k; /* more tmp */ XPoint *dummy = NULL; if (! dbufp) XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); if(spin){ 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 = gtk->mass / (d * sqrt(d)) * DELTAT * DELTAT * QCONS; else d = gtk->mass / (eps * sqrt(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 = 1 / (d * sqrt(d)) * DELTAT * QCONS; else d = 1 / (EPSILON * sqrt_EPSILON) * DELTAT * QCONS; d0 *= d; d1 *= d; d2 *= d; gt->vel[0] += d0 * gtk->mass; gt->vel[1] += d1 * gtk->mass; gt->vel[2] += d2 * gtk->mass; gtk->vel[0] -= d0 * gt->mass; gtk->vel[1] -= d1 * gt->mass; gtk->vel[2] -= d2 * gt->mass; } gt->pos[0] += gt->vel[0] * DELTAT; gt->pos[1] += gt->vel[1] * DELTAT; gt->pos[2] += gt->vel[2] * DELTAT; #if 1 // hacked and optimized by katahiromz { if (dbufp) { int count = gt->nstars; const XPoint *pt = gt->oldpoints; while (count-- > 0) { SetPixelV(display, pt->x, pt->y, 0); ++pt; } } XSetForeground(display, gc, MI_PIXEL(mi, gt->galcol)); { int count = gt->nstars; const XPoint *pt = gt->newpoints; const unsigned long rgb = gc->foreground_rgb; while (count-- > 0) { SetPixelV(display, pt->x, pt->y, rgb); ++pt; } } } #else if (dbufp) { 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)); XSetForeground(display, gc, MI_PIXEL(mi, gt->galcol)); XDrawPoints(display, window, gc, gt->newpoints, gt->nstars, CoordModeOrigin); #endif dummy = gt->oldpoints; gt->oldpoints = gt->newpoints; gt->newpoints = dummy; } gp->step++; if (gp->step > gp->f_hititerations * 4) startover(mi); }
static void startover(ModeInfo * 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; #if 1 // hacked by katahiromz gt->galcol = NRAND(NCOLORS); #else 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. */ #endif 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: "); #endif /*0 */ }
ENTRYPOINT void init_worm (ModeInfo * mi) { wormstruct *wp; int size = MI_SIZE(mi); int i, j; if (worms == NULL) { if ((worms = (wormstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (wormstruct))) == NULL) return; } wp = &worms[MI_SCREEN(mi)]; if (MI_NPIXELS(mi) <= 2 || MI_WIN_IS_USE3D(mi)) wp->nc = 2; else wp->nc = MI_NPIXELS(mi); if (wp->nc > NUMCOLORS) wp->nc = NUMCOLORS; free_worms(wp); wp->nw = MI_BATCHCOUNT(mi); if (wp->nw < -MINWORMS) wp->nw = NRAND(-wp->nw - MINWORMS + 1) + MINWORMS; else if (wp->nw < MINWORMS) wp->nw = MINWORMS; if (!wp->worm) wp->worm = (wormstuff *) malloc(wp->nw * sizeof (wormstuff)); if (!wp->size) wp->size = (int *) malloc(NUMCOLORS * sizeof (int)); wp->maxsize = (REDRAWSTEP + 1) * wp->nw; /* / wp->nc + 1; */ if (!wp->rects) wp->rects = (XRectangle *) malloc(wp->maxsize * NUMCOLORS * sizeof (XRectangle)); if (!init_table) { init_table = 1; for (i = 0; i < SEGMENTS; i++) { sintab[i] = SINF(i * 2.0 * M_PI / SEGMENTS); costab[i] = COSF(i * 2.0 * M_PI / SEGMENTS); } } wp->xsize = MI_WIN_WIDTH(mi); wp->ysize = MI_WIN_HEIGHT(mi); wp->zsize = MAXZ - MINZ + 1; if (MI_NPIXELS(mi) > 2) wp->chromo = NRAND(MI_NPIXELS(mi)); if (size < -MINSIZE) wp->circsize = NRAND(-size - MINSIZE + 1) + MINSIZE; else if (size < MINSIZE) wp->circsize = MINSIZE; else wp->circsize = size; for (i = 0; i < wp->nc; i++) { for (j = 0; j < wp->maxsize; j++) { wp->rects[i * wp->maxsize + j].width = wp->circsize; wp->rects[i * wp->maxsize + j].height = wp->circsize; } } (void) memset((char *) wp->size, 0, wp->nc * sizeof (int)); wp->wormlength = (int) sqrt(wp->xsize + wp->ysize) * MI_CYCLES(mi) / 8; /* Fudge this to something reasonable */ for (i = 0; i < wp->nw; i++) { wp->worm[i].circ = (XPoint *) malloc(wp->wormlength * sizeof (XPoint)); wp->worm[i].diffcirc = (int *) malloc(wp->wormlength * sizeof (int)); for (j = 0; j < wp->wormlength; j++) { wp->worm[i].circ[j].x = wp->xsize / 2; wp->worm[i].circ[j].y = wp->ysize / 2; if (MI_WIN_IS_USE3D(mi)) wp->worm[i].diffcirc[j] = 0; } wp->worm[i].dir = NRAND(SEGMENTS); wp->worm[i].dir2 = NRAND(SEGMENTS); wp->worm[i].tail = 0; wp->worm[i].x = wp->xsize / 2; wp->worm[i].y = wp->ysize / 2; wp->worm[i].z = SCREENZ - MINZ; wp->worm[i].redrawing = 0; } if (MI_WIN_IS_INSTALL(mi) && MI_WIN_IS_USE3D(mi)) { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_NONE_COLOR(mi)); XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), 0, 0, wp->xsize, wp->ysize); } else XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); }
static Bool startover(ModeInfo * mi) { unistruct *gp = &universes[MI_SCREEN(mi)]; int size = (int) 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_COUNT(mi) < -MINGALAXIES) free_galaxies(gp); gp->ngalaxies = MI_COUNT(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) if ((gp->galaxies = (Galaxy *) calloc(gp->ngalaxies, sizeof (Galaxy))) == NULL) { free_galaxy(MI_DISPLAY(mi), gp); return False; } for (i = 0; i < gp->ngalaxies; ++i) { Galaxy *gt = &gp->galaxies[i]; double sinw1, sinw2, cosw1, cosw2; if (MI_NPIXELS(mi) >= COLORS) do { gt->galcol = NRAND(COLORBASE) * COLORS; } while (gt->galcol + COLORBASE / 2 < GREEN + NOTGREEN && gt->galcol + COLORBASE / 2 > GREEN - NOTGREEN); else gt->galcol = 0; /* Galaxies still may have some green stars but are not all green. */ if (gt->stars != NULL) { free(gt->stars); gt->stars = (Star *) NULL; } gt->nstars = (NRAND(MAX_STARS / 2)) + MAX_STARS / 2; if ((gt->stars = (Star *) malloc(gt->nstars * sizeof (Star))) == NULL) { free_galaxy(MI_DISPLAY(mi), gp); return False; } 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) + Z_OFFSET; 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; st->Z_size = st->size; } } MI_CLEARWINDOW(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); #endif return True; }