예제 #1
0
static
void
draw_mesh(ModeInfo * mi, trianglestruct * tp, int d, int count)
{
    XPoint      p[3];
    int         first = 1;
    int         y_0, y_1, y_2;
    double      dinv = 0.2 / d;

    if ((tp->j == 0) && (tp->i == 0)) {
#if 0 /* jwz */
        XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
#else
        {
            int x = 0;
            int y = 0;
            int x2 = MI_WIN_WIDTH(mi);
            int y2 = tp->ypos[0];
            XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi));
            XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
                           x, y, x2, y2);
        }
#endif
    }
    for (; (tp->j < tp->size) && (count > 0); tp->j += ((count) ? d : 0)) {
        for (tp->i = (first) ? tp->i : 0, first = 0;
                (tp->i < MAX_SIZE - tp->j) && (count > 0);
                tp->i += d, count--) {
            if (tp->i + tp->j < tp->size) {
                calc_points1(tp, d, &y_0, &y_1, &y_2, p);
                draw_atriangle(mi, p, y_0, y_1, y_2, dinv);
            }
            if (tp->i + tp->j + d < tp->size) {
                calc_points2(tp, d, &y_0, &y_1, &y_2, p);
                draw_atriangle(mi, p, y_0, y_1, y_2, dinv);
            }
        }
    }

    if (tp->j == tp->size) {
        tp->init_now = 1;
    }
}
예제 #2
0
static
void
draw_atriangle(ModeInfo * mi, XPoint * p, int y_0, int y_1, int y_2, double dinv)
{
    Display    *display = MI_DISPLAY(mi);
    Window      window = MI_WINDOW(mi);
    GC          gc = MI_GC(mi);

    if (MI_NCOLORS(mi) > 2) {	/* color */
        int         dmax, dmin;
        long        color;

        dmin = MIN(y_0, y_1);
        dmin = MIN(dmin, y_2);
        dmax = MAX(y_0, y_1);
        dmax = MAX(dmax, y_2);

        if (dmax == 0) {
            color = BLUE;
        } else {
            color = MI_NCOLORS(mi) -
                    (int) ((double) MI_NCOLORS(mi) / M_PI_2 * atan(dinv * (dmax - dmin)));
        }

        XSetForeground(display, gc, mi->colors[color % MI_NCOLORS(mi)].pixel);
        XFillPolygon(display, window, gc, p, 3, Convex, CoordModeOrigin);
    } else {
        /* mono */
#ifdef BACKFACE_REMOVAL
        XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));
        XFillPolygon(display, window, gc, p, 3, Convex, CoordModeOrigin);
#endif
        XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
        XDrawLine(display, window, gc, p[0].x, p[0].y, p[1].x, p[1].y);
        XDrawLine(display, window, gc, p[1].x, p[1].y, p[2].x, p[2].y);
        XDrawLine(display, window, gc, p[2].x, p[2].y, p[0].x, p[0].y);
    }
}
예제 #3
0
ENTRYPOINT void
draw_bouboule(ModeInfo * mi)
/****************/

{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = MI_GC(mi);
	StarField  *sp = &starfield[MI_SCREEN(mi)];
	int         i, diff = 0;
	double      CX, CY, CZ, SX, SY, SZ;
	Star       *star;
	XArc       *arc = NULL, *arcleft = NULL;

#ifdef HAVE_COCOA	/* Don't second-guess Quartz's double-buffering */
    XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
#endif

#if (ADAPT_ERASE == 1)
	struct timeval tv1;
	struct timeval tv2;

#endif

#if ((USEOLDXARCS == 0) || (ADAPT_ERASE == 1))
	short       x_1, y_1, x_2, y_2;

	/* bounding rectangle around the old starfield,
	 * for erasing with the smallest rectangle
	 * instead of filling the whole screen */
	int         maxdiff = 0;	/* maximal distance between left and right */

	/* star in 3d mode, otherwise 0 */
#endif

#if ((USEOLDXARCS == 0) || (ADAPT_ERASE == 1))
	if (MI_WIN_IS_USE3D(mi)) {
		maxdiff = (int) MAXDIFF;
	}
	x_1 = (int) sp->x.value - (int) sp->sizex.value -
		sp->max_star_size - maxdiff;
	y_1 = (int) sp->y.value - (int) sp->sizey.value -
		sp->max_star_size;
	x_2 = 2 * ((int) sp->sizex.value + sp->max_star_size + maxdiff);
	y_2 = 2 * ((int) sp->sizey.value + sp->max_star_size);
#endif
	/* We make variables vary. */
	sinvary(&sp->thetax);
	sinvary(&sp->thetay);
	sinvary(&sp->thetaz);

	sinvary(&sp->x);
	sinvary(&sp->y);
	if (MI_WIN_IS_USE3D(mi))
		sinvary(&sp->z);

	/* A little trick to prevent the bouboule from being
	 * bigger than the screen */
	sp->sizex.maximum =
		MIN(((double) sp->width) - sp->x.value,
		    sp->x.value);
	sp->sizex.minimum = sp->sizex.maximum / 3.0;

	/* Another trick to make the ball not too flat */
	sp->sizey.minimum =
		MAX(sp->sizex.value / MAX_SIZEX_SIZEY,
		    sp->sizey.maximum / 3.0);
	sp->sizey.maximum =
		MIN(sp->sizex.value * MAX_SIZEX_SIZEY,
		    MIN(((double) sp->height) - sp->y.value,
			sp->y.value));

	sinvary(&sp->sizex);
	sinvary(&sp->sizey);

	/*
	 * We calculate the rotation matrix values. We just make the
	 * rotation on the fly, without using a matrix.
	 * Star positions are recorded as unit vectors pointing in various
	 * directions. We just make them all rotate.
	 */
	CX = cos(sp->thetax.value);
	SX = sin(sp->thetax.value);
	CY = cos(sp->thetay.value);
	SY = sin(sp->thetay.value);
	CZ = cos(sp->thetaz.value);
	SZ = sin(sp->thetaz.value);

	for (i = 0; i < sp->NbStars; i++) {
		star = &(sp->star[i]);
		arc = &(sp->xarc[i]);
		if (MI_WIN_IS_USE3D(mi)) {
			arcleft = &(sp->xarcleft[i]);
			/* to help the eyes, the starfield is always as wide as */
			/* deep, so .sizex.value can be used. */
			diff = (int) GETZDIFF(sp->sizex.value *
				      ((SY * CX) * star->x + (SX) * star->y +
				       (CX * CY) * star->z) + sp->z.value);
		}
		arc->x = (short) ((sp->sizex.value *
				   ((CY * CZ - SX * SY * SZ) * star->x +
				    (-CX * SZ) * star->y +
				    (SY * CZ + SZ * SX * CY) * star->z) +
				   sp->x.value));
		arc->y = (short) ((sp->sizey.value *
				   ((CY * SZ + SX * SY * CZ) * star->x +
				    (CX * CZ) * star->y +
				    (SY * SZ - SX * CY * CZ) * star->z) +
				   sp->y.value));

		if (MI_WIN_IS_USE3D(mi)) {
			arcleft->x = (short) ((sp->sizex.value *
					((CY * CZ - SX * SY * SZ) * star->x +
					 (-CX * SZ) * star->y +
					 (SY * CZ + SZ * SX * CY) * star->z) +
					       sp->x.value));
			arcleft->y = (short) ((sp->sizey.value *
					((CY * SZ + SX * SY * CZ) * star->x +
					 (CX * CZ) * star->y +
					 (SY * SZ - SX * CY * CZ) * star->z) +
					       sp->y.value));
			arc->x += diff;
			arcleft->x -= diff;
		}
		if (star->size != 0) {
			arc->x -= star->size;
			arc->y -= star->size;
			if (MI_WIN_IS_USE3D(mi)) {
				arcleft->x -= star->size;
				arcleft->y -= star->size;
			}
		}
	}

	/* First, we erase the previous starfield */
	if (MI_WIN_IS_INSTALL(mi) && MI_WIN_IS_USE3D(mi))
		XSetForeground(display, gc, MI_NONE_COLOR(mi));
	else
		XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));

#if (ADAPT_ERASE == 1)
	if (sp->hasbeenchecked == 0) {
		/* We just calculate which method is the faster and eventually free
		 * the oldxarc list */
		if (sp->xarc_time >
		    ADAPT_ARC_PREFERED * sp->rect_time) {
			sp->hasbeenchecked = -2;	/* XFillRectangle mode */
			(void) free((void *) sp->oldxarc);
			sp->oldxarc = NULL;
			if (MI_WIN_IS_USE3D(mi)) {
				(void) free((void *) sp->oldxarcleft);
			  sp->oldxarcleft = NULL;
			}
		} else {
			sp->hasbeenchecked = -1;	/* XFillArcs mode */
		}
	}
	if (sp->hasbeenchecked == -2) {
		/* Erasing is done with XFillRectangle */
		XFillRectangle(display, window, gc,
			       x_1, y_1, x_2, y_2);
	} else if (sp->hasbeenchecked == -1) {
		/* Erasing is done with XFillArcs */
		XFillArcs(display, window, gc,
			  sp->oldxarc, sp->NbStars);
		if (MI_WIN_IS_USE3D(mi))
			XFillArcs(display, window, gc,
				  sp->oldxarcleft, sp->NbStars);
	} else {
		long        usec;

		if (sp->hasbeenchecked > ADAPT_CHECKS) {
#ifdef GETTIMEOFDAY_TWO_ARGS
			(void) gettimeofday(&tv1, NULL);
#else
			(void) gettimeofday(&tv1);
#endif
			XFillRectangle(display, window, gc,
				       x_1, y_1, x_2, y_2);
#ifdef GETTIMEOFDAY_TWO_ARGS
			(void) gettimeofday(&tv2, NULL);
#else
			(void) gettimeofday(&tv2);
#endif
			usec = (tv2.tv_sec - tv1.tv_sec) * 1000000;
			if (usec + tv2.tv_usec - tv1.tv_usec > 0) {
				sp->rect_time += usec + tv2.tv_usec - tv1.tv_usec;
				sp->hasbeenchecked--;
			}
		} else {
#ifdef GETTIMEOFDAY_TWO_ARGS
			(void) gettimeofday(&tv1, NULL);
#else
			(void) gettimeofday(&tv1);
#endif
			XFillArcs(display, window, gc,
				  sp->oldxarc, sp->NbStars);
			if (MI_WIN_IS_USE3D(mi))
				XFillArcs(display, window, gc,
					  sp->oldxarcleft, sp->NbStars);
#ifdef GETTIMEOFDAY_TWO_ARGS
			(void) gettimeofday(&tv2, NULL);
#else
			(void) gettimeofday(&tv2);
#endif
			usec = (tv2.tv_sec - tv1.tv_sec) * 1000000;
			if (usec + tv2.tv_usec - tv1.tv_usec > 0) {
				sp->xarc_time += usec + tv2.tv_usec - tv1.tv_usec;
				sp->hasbeenchecked--;
			}
		}
	}
#else
#if (USEOLDXARCS == 1)
	XFillArcs(display, window, gc,
		  sp->oldxarc, sp->NbStars);
	if (MI_WIN_IS_USE3D(mi))
		XFillArcs(display, window, gc,
			  sp->oldxarcleft, sp->NbStars);
#else
	XFillRectangle(display, window, gc,
		       x_1, y_1, x_2, y_2);
#endif
#endif

	/* Then we draw the new one */
	if (MI_WIN_IS_USE3D(mi)) {
		if (MI_WIN_IS_INSTALL(mi))
			XSetFunction(display, gc, GXor);
		XSetForeground(display, gc, MI_RIGHT_COLOR(mi));
		XFillArcs(display, window, gc, sp->xarc, sp->NbStars);
		XSetForeground(display, gc, MI_LEFT_COLOR(mi));
		XFillArcs(display, window, gc, sp->xarcleft, sp->NbStars);
		if (MI_WIN_IS_INSTALL(mi))
			XSetFunction(display, gc, GXcopy);
	} else {
		XSetForeground(display, gc, sp->color);
		XFillArcs(display, window, gc, sp->xarc, sp->NbStars);
	}

#if ((USEOLDXARCS == 1) || (ADAPT_ERASE == 1))
#if (ADAPT_ERASE == 1)
	if (sp->hasbeenchecked >= -1) {
		arc = sp->xarc;
		sp->xarc = sp->oldxarc;
		sp->oldxarc = arc;
		if (MI_WIN_IS_USE3D(mi)) {
			arcleft = sp->xarcleft;
			sp->xarcleft = sp->oldxarcleft;
			sp->oldxarcleft = arcleft;
		}
	}
#else
	arc = sp->xarc;
	sp->xarc = sp->oldxarc;
	sp->oldxarc = arc;
	if (MI_WIN_IS_USE3D(mi)) {
		arcleft = sp->xarcleft;
		sp->xarcleft = sp->oldxarcleft;
		sp->oldxarcleft = arcleft;
	}
#endif
#endif

	/* We set up the color for the next drawing */
	if (!MI_WIN_IS_USE3D(mi) && MI_NPIXELS(mi) > 2 &&
	    (++sp->colorchange >= COLOR_CHANGES)) {
		sp->colorchange = 0;
		if (++sp->colorp >= MI_NPIXELS(mi))
			sp->colorp = 0;
		sp->color = MI_PIXEL(mi, sp->colorp);
	}
}
예제 #4
0
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 = &gt->stars[j];
      XPoint     *newp = &gt->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);
}