Example #1
0
void
draw_gasket(ModeInfo * mi)
{
  gasketstruct *gp = &gasket[MI_SCREEN(mi)];
  Display      *display = MI_DISPLAY(mi);
  Window        window = MI_WINDOW(mi);
  int           angle_incr = 1;

  if (!gp->glx_context) return;

  glDrawBuffer(GL_BACK);

  if (max_depth > 10)
    max_depth = 10;

  MI_IS_DRAWN(mi) = True;

  glXMakeCurrent(display, window, *(gp->glx_context));
  draw(mi);

  /* rotate */
  gp->angle = (int) (gp->angle + angle_incr) % 360;

  rotate(&gp->rotx, &gp->dx, &gp->ddx, gp->d_max, MI_IS_VERBOSE(mi));
  rotate(&gp->roty, &gp->dy, &gp->ddy, gp->d_max, MI_IS_VERBOSE(mi));
  rotate(&gp->rotz, &gp->dz, &gp->ddz, gp->d_max, MI_IS_VERBOSE(mi));

  /* if (mi->fps_p) do_fps (mi); */

  if (MI_IS_FPS(mi)) do_fps (mi);
  glFinish();
  glXSwapBuffers(display, window);
}
Example #2
0
/* Direction angle of an edge. */
static      angle_c
vertex_dir(ModeInfo * mi, fringe_node_c * vertex, unsigned side)
{
	tiling_c   *tp = &tilings[MI_SCREEN(mi)];
	fringe_node_c *v2 =
	(side == S_LEFT ? vertex->next : vertex->prev);
	register int i;

	for (i = 0; i < 5; i++)
		switch (v2->fived[i] - vertex->fived[i]) {
			case 1:
				return 2 * i;
			case -1:
				return (2 * i + 5) % 10;
		}
	tp->done = True;
	if (MI_IS_VERBOSE(mi)) {
		(void) fprintf(stderr,
		       "Weirdness in vertex_dir (this has been reported)\n");
		for (i = 0; i < 5; i++)
			(void) fprintf(stderr, "v2->fived[%d]=%d, vertex->fived[%d]=%d\n",
				       i, v2->fived[i], i, vertex->fived[i]);
	}
	tp->busyLoop = CELEBRATE;
	return 0;
}
Example #3
0
static fringe_node_c *
alloc_vertex(ModeInfo * mi, angle_c dir, fringe_node_c * from, tiling_c * tp)
{
	fringe_node_c *v;

	if ((v = ALLOC_NODE(fringe_node_c)) == NULL) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "No memory in alloc_vertex()\n");
		}
		tp->busyLoop = CELEBRATE;
		return v;
	}
	*v = *from;
	add_unit_vec(dir, v->fived);
	fived_to_loc(v->fived, tp, &(v->loc));
	if (v->loc.x < 0 || v->loc.y < 0
	    || v->loc.x >= tp->width || v->loc.y >= tp->height) {
		v->off_screen = True;
		if (v->loc.x < -tp->width || v->loc.y < -tp->height
		  || v->loc.x >= 2 * tp->width || v->loc.y >= 2 * tp->height)
			tp->done = True;
	} else {
		v->off_screen = False;
		tp->fringe.n_nodes++;
	}
	v->n_tiles = 0;
	v->rule_mask = (1 << N_VERTEX_RULES) - 1;
	v->list_ptr = 0;
	return v;
}
Example #4
0
/*-
 * Delete this vertex.  If the vertex is a member of the forced vertex queue,
 * also remove that entry.  We assume that the vertex is no longer
 * connected to the fringe.  Note that tp->fringe.nodes must not point to
 * the vertex being deleted.
 */
static void
delete_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
{
	if (tp->fringe.nodes == vertex) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in delete_penrose()\n");
			(void) fprintf(stderr, "tp->fringe.nodes == vertex\n");
		}
		tp->busyLoop = CELEBRATE;
	}
	if (vertex->list_ptr != 0) {
		forced_node_c *node = *vertex->list_ptr;

		*vertex->list_ptr = node->next;
		if (node->next != 0)
			node->next->vertex->list_ptr = vertex->list_ptr;
		free(node);
		tp->forced.n_nodes--;
		if (!vertex->off_screen)
			tp->forced.n_visible--;
	}
	if (!vertex->off_screen)
		tp->fringe.n_nodes--;
	free(vertex);
}
Example #5
0
/*-
 * Update the status of this vertex on the forced vertex queue.  If
 * the vertex has become untileable set tp->done.  This is supposed
 * to detect dislocations -- never call this routine with a completely
 * tiled vertex.
 *
 * Check for untileable vertices in check_vertex and stop tiling as
 * soon as one finds one.  I don't know if it is possible to run out
 * of forced vertices while untileable vertices exist (or will
 * cavities inevitably appear).  If this can happen, add_random_tile
 * might get called with an untileable vertex, causing ( n <= 1).
 * (This is what the tp->done checks for).
 *
 * A delayLoop celebrates the dislocation.
 */
static void
check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
{
	rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
	int         n_hits = match_rules(vertex, hits, False);
	unsigned    forced_sides = 0;

	if (vertex->rule_mask == 0) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Dislocation occurred!\n");
		}
		tp->busyLoop = CELEBRATE;	/* Should be able to recover */
	}
	if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ ))
		forced_sides |= S_LEFT;
	if (1 == find_completions(vertex, hits, n_hits, S_RIGHT, 0 /*, False */ ))
		forced_sides |= S_RIGHT;
	if (forced_sides == 0) {
		if (vertex->list_ptr != 0) {
			forced_node_c *node = *vertex->list_ptr;

			*vertex->list_ptr = node->next;
			if (node->next != 0)
				node->next->vertex->list_ptr = vertex->list_ptr;
			free(node);
			tp->forced.n_nodes--;
			if (!vertex->off_screen)
				tp->forced.n_visible--;
			vertex->list_ptr = 0;
		}
	} else {
		forced_node_c *node;

		if (vertex->list_ptr == 0) {
			if ((node = ALLOC_NODE(forced_node_c)) == NULL)
				return;
			node->vertex = vertex;
			node->next = tp->forced.first;
			if (tp->forced.first != 0)
				tp->forced.first->vertex->list_ptr = &(node->next);
			tp->forced.first = node;
			vertex->list_ptr = &(tp->forced.first);
			tp->forced.n_nodes++;
			if (!vertex->off_screen)
				tp->forced.n_visible++;
		} else
			node = *vertex->list_ptr;
		node->forced_sides = forced_sides;
	}
}
Example #6
0
void
make_uniform_colormap(ModeInfo * mi, Colormap cmap,
		      XColor * colors, int *ncolorsP,
		      Bool allocate_p,
		      Bool * writable_pP)
{
	int         ncolors = *ncolorsP;
	Bool        wanted_writable = (allocate_p && writable_pP && *writable_pP);

	double      S = ((double) (LRAND() % 34) + 66) / 100.0;		/* range 66%-100% */
	double      V = ((double) (LRAND() % 34) + 66) / 100.0;		/* range 66%-100% */

	if (*ncolorsP <= 0)
		return;

	/* If this visual doesn't support writable cells, don't bother trying. */
	if (wanted_writable && !has_writable_cells(mi))
		*writable_pP = False;

      RETRY_NON_WRITABLE:
	make_color_ramp(MI_DISPLAY(mi), cmap,
			0, S, V,
			359, S, V,
			colors, &ncolors,
			False, True, wanted_writable);

	/* If we tried for writable cells and got none, try for non-writable. */
	if (allocate_p && *ncolorsP == 0 && writable_pP && *writable_pP) {
		ncolors = *ncolorsP;
		*writable_pP = False;
		goto RETRY_NON_WRITABLE;
	}
	if (MI_IS_VERBOSE(mi) || MI_IS_DEBUG(mi))
		complain(*ncolorsP, ncolors, wanted_writable,
			 wanted_writable && *writable_pP);

	*ncolorsP = ncolors;
}
Example #7
0
/*-
 * Add a forced tile to a given forced vertex.  Basically an easy job,
 * since we know what to add.  But it might fail if adding the tile
 * would cause some untiled area to become enclosed.  There is also another
 * more exotic culprit: we might have a dislocation.  Fortunately, they
 * are very rare (the PRL article reported that perfect tilings of over
 * 2^50 tiles had been generated).  There is a version of the algorithm
 * that doesn't produce dislocations, but it's a lot hairier than the
 * simpler version I used.
 */
static int
add_forced_tile(ModeInfo * mi, forced_node_c * node)
{
	tiling_c   *tp = &tilings[MI_SCREEN(mi)];
	unsigned    side;
	vertex_type_c vtype;
	rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
	int         n;

	if (node->forced_sides == (S_LEFT | S_RIGHT))
		side = NRAND(2) ? S_LEFT : S_RIGHT;
	else
		side = node->forced_sides;
	n = match_rules(node->vertex, hits, True);
	n = find_completions(node->vertex, hits, n, side, &vtype /*, True */ );
	if (n <= 0) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in add_forced_tile()\n");
			(void) fprintf(stderr, "n = %d\n", n);
		}
	}
	return add_tile(mi, node->vertex, side, vtype);
}
Example #8
0
ENTRYPOINT void
init_hop(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	GC          gc = MI_GC(mi);
	double      range;
	hopstruct  *hp;

	if (hops == NULL) {
		if ((hops = (hopstruct *) calloc(MI_NUM_SCREENS(mi),
						 sizeof (hopstruct))) == NULL)
			return;
	}
	hp = &hops[MI_SCREEN(mi)];

	hp->centerx = MI_WIDTH(mi) / 2;
	hp->centery = MI_HEIGHT(mi) / 2;
	/* Make the other operations less common since they are less interesting */
	if (MI_IS_FULLRANDOM(mi)) {
		hp->op = NRAND(OPS);
	} else {
		if (martin)
			hp->op = MARTIN;
		else if (popcorn)
			hp->op = POPCORN;
		else if (ejk1)
			hp->op = EJK1;
		else if (ejk2)
			hp->op = EJK2;
		else if (ejk3)
			hp->op = EJK3;
		else if (ejk4)
			hp->op = EJK4;
		else if (ejk5)
			hp->op = EJK5;
		else if (ejk6)
			hp->op = EJK6;
		else if (rr)
			hp->op = RR;
		else if (jong)
			hp->op = JONG;
		else if (sine)
			hp->op = SINE;
		else
			hp->op = NRAND(OPS);
	}

	range = sqrt((double) hp->centerx * hp->centerx +
	     (double) hp->centery * hp->centery) / (1.0 + LRAND() / MAXRAND);
	hp->i = hp->j = 0.0;
	hp->inc = (int) ((LRAND() / MAXRAND) * 200) - 100;
#undef XMARTIN
	switch (hp->op) {
		case MARTIN:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 1500.0 + 40.0;
			hp->b = (LRAND() / MAXRAND) * 17.0 + 3.0;
			hp->c = (LRAND() / MAXRAND) * 3000.0 + 100.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0;
			hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0;
			if (LRAND() & 1)
				hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0;
			else
				hp->c = 0.0;
#endif
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "sqrt a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK1:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 500.0;
			hp->c = (LRAND() / MAXRAND) * 100.0 + 10.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 40.0;
#endif
			hp->b = (LRAND() / MAXRAND) * 0.4;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk1 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK2:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 500.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0;
#endif
			hp->b = pow(10.0, 6.0 + (LRAND() / MAXRAND) * 24.0);
			if (LRAND() & 1)
				hp->b = -hp->b;
			hp->c = pow(10.0, (LRAND() / MAXRAND) * 9.0);
			if (LRAND() & 1)
				hp->c = -hp->c;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk2 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK3:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 500.0;
			hp->c = (LRAND() / MAXRAND) * 80.0 + 30.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 70.0;
#endif
			hp->b = (LRAND() / MAXRAND) * 0.35 + 0.5;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk3 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK4:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 1000.0;
			hp->c = (LRAND() / MAXRAND) * 40.0 + 30.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 2.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0;
#endif
			hp->b = (LRAND() / MAXRAND) * 9.0 + 1.0;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk4 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK5:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 600.0;
			hp->c = (LRAND() / MAXRAND) * 90.0 + 20.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 2.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0;
#endif
			hp->b = (LRAND() / MAXRAND) * 0.3 + 0.1;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk5 a=%g, b=%g, c=%g\n", hp->a, hp->b, hp->c);
			break;
		case EJK6:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 100.0 + 550.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 30.0;
#endif
			hp->b = (LRAND() / MAXRAND) + 0.5;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "ejk6 a=%g, b=%g\n", hp->a, hp->b);
			break;
		case RR:
#ifdef XMARTIN
			hp->a = (LRAND() / MAXRAND) * 100.0;
			hp->b = (LRAND() / MAXRAND) * 20.0;
			hp->c = (LRAND() / MAXRAND) * 200.0;
#else
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 40.0;
			hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 200.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * range / 20.0;
#endif
			hp->d = (LRAND() / MAXRAND) * 0.9;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "rr a=%g, b=%g, c=%g, d=%g\n",
					       hp->a, hp->b, hp->c, hp->d);
			break;
		case POPCORN:
			hp->a = 0.0;
			hp->b = 0.0;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.24 + 0.25;
			hp->inc = 100;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "popcorn a=%g, b=%g, c=%g, d=%g\n",
					       hp->a, hp->b, hp->c, hp->d);
			break;
		case JONG:
			hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI;
			hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI;
			hp->c = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI;
			hp->d = ((LRAND() / MAXRAND) * 2.0 - 1.0) * M_PI;
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "jong a=%g, b=%g, c=%g, d=%g\n",
					       hp->a, hp->b, hp->c, hp->d);
			break;
		case SINE:	/* MARTIN2 */
#ifdef XMARTIN
			hp->a = M_PI + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.07;
#else
			hp->a = M_PI + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.7;
#endif
			if (MI_IS_VERBOSE(mi))
				(void) fprintf(stdout, "sine a=%g\n", hp->a);
			break;
	}
	if (MI_NPIXELS(mi) > 2)
		hp->pix = NRAND(MI_NPIXELS(mi));
	hp->bufsize = MI_COUNT(mi);

	if (hp->pointBuffer == NULL) {
		if ((hp->pointBuffer = (XPoint *) malloc(hp->bufsize *
				sizeof (XPoint))) == NULL)
			return;
	}

#ifndef STANDALONE
	MI_CLEARWINDOW(mi);
#endif

	XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
	hp->count = 0;
}
Example #9
0
void
init_life1d(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	int         size = MI_SIZE(mi);
	int         i;
	life1dstruct *lp;

	if (life1ds == NULL) {
		if ((life1ds = (life1dstruct *) calloc(MI_NUM_SCREENS(mi),
					     sizeof (life1dstruct))) == NULL)
			return;
	}
	lp = &life1ds[MI_SCREEN(mi)];

	if (!init_stuff(mi)) {
		free_life1d(display, lp);
		return;
	}

	lp->screen_generation = 0;
	lp->row = 0;

	if (totalistic) {
		maxstates = MAXSTATES;
		maxradius = 4;
		maxsum_size = (maxstates - 1) * (maxradius * 2 + 1) + 1;
	} else {
		maxstates = MAXSTATES - 1;
		maxradius = 1;
		maxsum_size = (int) power(maxstates, (2 * maxradius + 1));
	}
	if (lp->nextstate == NULL) {
		if ((lp->nextstate = (char *) malloc(maxsum_size *
				sizeof (char))) == NULL) {
			free_life1d(display, lp);
			return;
		}
	}

	if (lp->init_bits == 0) {
		XGCValues   gcv;

		gcv.fill_style = FillOpaqueStippled;
		if ((lp->stippledGC = XCreateGC(display, window, GCFillStyle,
				&gcv)) == None) {
			free_life1d(display, lp);
			return;
		}
		for (i = 0; i < MAXSTATES - 1; i++) {
			LIFE1DBITS(stipples[i + NUMSTIPPLES - MAXSTATES + 1],
				   STIPPLESIZE, STIPPLESIZE);
		}
		LIFE1DBITS(stipples[NUMSTIPPLES / 2],
			   STIPPLESIZE, STIPPLESIZE);	/* grey */
	}
	if (lp->newcells != NULL)
		free(lp->newcells);
	if (lp->oldcells != NULL)
		free(lp->oldcells);
	if (lp->buffer != NULL)
		free(lp->buffer);
	if (lp->previousBuffer != NULL)
		free(lp->previousBuffer);
	lp->previousBuffer = (unsigned char *) NULL;
	lp->width = MI_WIDTH(mi);
	lp->height = MI_HEIGHT(mi);
	if (lp->width < 2)
		lp->width = 2;
	if (lp->height < 2)
		lp->height = 2;
	if (size == 0 ||
	 MINGRIDSIZE * size > lp->width || MINGRIDSIZE * size > lp->height) {
		if (lp->width > MINGRIDSIZE * lp->logo->width &&
		    lp->height > MINGRIDSIZE * lp->logo->height) {
			lp->pixelmode = False;
			lp->xs = lp->logo->width;
			lp->ys = lp->logo->height;
		} else
		{
			int min = MIN(lp->width, lp->height) / (12 * MINGRIDSIZE);
			int max = MIN(lp->width, lp->height) / (4 * MINGRIDSIZE);


			lp->xs = lp->ys = MAX(MINSIZE, min + NRAND(max - min + 1));
			lp->pixelmode = True;
		}
	} else {
		lp->pixelmode = True;
		if (size < -MINSIZE) {
			lp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(lp->width, lp->height) /
				      MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
		} else if (size < MINSIZE) {
			lp->ys = MINSIZE;
		} else {
			lp->ys = MIN(size, MAX(MINSIZE, MIN(lp->width, lp->height) /
					       MINGRIDSIZE));
		}
		lp->xs = lp->ys;
	}
	lp->ncols = MAX(lp->width / lp->xs, 2);
	lp->nrows = MAX(lp->height / lp->ys, 2);
	lp->border = (lp->nrows / 2 + 1) * MI_CYCLES(mi);
	if ((lp->newcells = (unsigned char *) calloc(lp->ncols + 2 * lp->border,
			sizeof (unsigned char))) == NULL) {
		free_life1d(display, lp);
		return;
	}

	if ((lp->oldcells = (unsigned char *) calloc(lp->ncols + 2 *
			(maxradius + lp->border),
			sizeof (unsigned char))) == NULL) {
		free_life1d(display, lp);
		return;
	}

	if ((lp->buffer = (unsigned char *) calloc(lp->ncols * lp->nrows,
			sizeof (unsigned char))) == NULL) {
		free_life1d(display, lp);
		return;
	}

	lp->xb = (lp->width - lp->xs * lp->ncols) / 2;
	lp->yb = (lp->height - lp->ys * lp->nrows) / 2;

	GetRule(lp, (int) NRAND((totalistic) ? TOTALISTICRULES : LCAURULES));
	if (MI_IS_VERBOSE(mi)) {
		(void) fprintf(stdout, "colors %d, radius %d, code %ld, ",
			       lp->k, lp->r, lp->code);
		if (totalistic) {
			(void) fprintf(stdout, "totalistic rule ");
			for (i = (lp->k - 1) * (lp->r * 2 + 1); i >= 0; i--)
				(void) fprintf(stdout, "%d", (int) lp->nextstate[i]);
		} else {
			(void) fprintf(stdout, "LCAU rule ");
			for (i = (int) power(lp->k, (lp->r * 2 + 1)); i >= 0; i--)
				(void) fprintf(stdout, "%d", (int) lp->nextstate[i]);
		}
		(void) fprintf(stdout, "\n");
	}
	if (MI_NPIXELS(mi) > 2) {
		int offset = NRAND(MI_NPIXELS(mi));

		for (i = 0; i < lp->k - 1; i++) {
			lp->colors[i] = ((offset +
				(i * MI_NPIXELS(mi) / (lp->k - 1))) %
				MI_NPIXELS(mi));
		}
	}
	RandomSoup(lp, 40, 25);
	(void) memcpy((char *) (lp->oldcells + maxradius + lp->border),
		      (char *) (lp->newcells + lp->border), lp->ncols);
	lp->busyLoop = 0;

	MI_CLEARWINDOWCOLORMAP(mi, lp->backGC, lp->black);
}
Example #10
0
/* Constructs the GL shapes of the current molecule
 */
static void
build_molecule (ModeInfo *mi)
{
  molecule_configuration *mc = &mcs[MI_SCREEN(mi)];
  int wire = cur_wire;
  int i;

  molecule *m = &mc->molecules[mc->which];

  if (wire)
    {
      glDisable(GL_CULL_FACE);
      glDisable(GL_LIGHTING);
      glDisable(GL_LIGHT0);
      glDisable(GL_DEPTH_TEST);
      glDisable(GL_NORMALIZE);
      glDisable(GL_CULL_FACE);
    }
  else
    {
      glEnable(GL_CULL_FACE);
      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_NORMALIZE);
      glEnable(GL_CULL_FACE);
    }

  if (!wire)
    set_atom_color (mi, 0, False);

  if (do_bonds)
    for (i = 0; i < m->nbonds; i++)
      {
        molecule_bond *b = &m->bonds[i];
        molecule_atom *from = get_atom(m->atoms, m->natoms, b->from,
		MI_IS_VERBOSE(mi));
        molecule_atom *to   = get_atom(m->atoms, m->natoms, b->to,
		MI_IS_VERBOSE(mi));

        if (wire)
          {
            glBegin(GL_LINES);
            glVertex3f(from->x, from->y, from->z);
            glVertex3f(to->x,   to->y,   to->z);
            glEnd();
          }
        else
          {
            int faces = (scale_down ? TUBE_FACES_2 : TUBE_FACES);
# ifdef SMOOTH_TUBE
            int smooth = True;
# else
            int smooth = False;
# endif
            GLfloat thickness = 0.07 * b->strength;
            GLfloat cap_size = 0.03;
            if (thickness > 0.3)
              thickness = 0.3;

            tube (from->x, from->y, from->z,
                  to->x,   to->y,   to->z,
                  thickness, cap_size,
                  faces, smooth, !do_atoms, wire);
          }
      }

  for (i = 0; i < m->natoms; i++)
    {
      molecule_atom *a = &m->atoms[i];
      int i;

      if (!wire && do_atoms)
        {
          GLfloat size = atom_size (a);
          set_atom_color (mi, a, False);
          sphere (a->x, a->y, a->z, size, wire);
        }

      if (do_labels)
        {
          glPushAttrib (GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
          glDisable (GL_LIGHTING);
          glDisable (GL_DEPTH_TEST);

          if (!wire)
            set_atom_color (mi, a, True);

          glRasterPos3f (a->x, a->y, a->z);

          {
            GLdouble mm[17], pm[17];
            GLint vp[5];
            GLdouble wx=-1, wy=-1, wz=-1;
            glGetDoublev (GL_MODELVIEW_MATRIX, mm);
            glGetDoublev (GL_PROJECTION_MATRIX, pm);
            glGetIntegerv (GL_VIEWPORT, vp);

            /* Convert 3D coordinates to window coordinates */
            gluProject (a->x, a->y, a->z, mm, pm, vp, &wx, &wy, &wz);

            /* Fudge the window coordinates to center the string */
            wx -= string_width (mc->xfont1, a->label) / 2;
            wy -= mc->xfont1->descent;

            /* Convert new window coordinates back to 3D coordinates */
            gluUnProject (wx, wy, wz, mm, pm, vp, &wx, &wy, &wz);
            glRasterPos3f (wx, wy, wz);
          }

          for (i = 0; i < (int) strlen(a->label); i++)
            glCallList (mc->font1_dlist + (int)(a->label[i]));

          glPopAttrib();
        }
    }

  if (do_bbox)
    draw_bounding_box (mi);

  if (do_titles && m->label && *m->label)
    print_title_string (mi, m->label,
                        10, MI_HEIGHT(mi) - 10,
                        mc->xfont2->ascent + mc->xfont2->descent);
}
Example #11
0
void
draw_molecule (ModeInfo *mi)
{
/*  static time_t last = 0; */
  time_t now = time ((time_t *) 0);
  molecule_configuration *mc;
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);

  if (mcs == NULL)
	return;
  mc = &mcs[MI_SCREEN(mi)];
  if (!mc->glx_context)
    return;

  MI_IS_DRAWN(mi) = True;

  if (last + timeout <= now)   /* randomize molecules every -timeout seconds */
    {
      if (mc->nmolecules == 1)
        {
          if (last != 0) goto SKIP;
          mc->which = 0;
        }
      else if (last == 0)
        {
          mc->which = NRAND(mc->nmolecules);
        }
      else
        {
          int n = mc->which;
          while (n == mc->which)
            n = NRAND(mc->nmolecules);
          mc->which = n;
        }

      last = now;


      glNewList (mc->molecule_dlist, GL_COMPILE);
      ensure_bounding_box_visible (mi);
      if (MI_IS_ICONIC(mi))
        {do_labels = False;
	 do_bonds  = True;
         do_titles = False;
	}
      else
        {
      do_labels = orig_do_labels;
      do_bonds = orig_do_bonds;
      do_titles = orig_do_titles;
        }
      cur_wire = orig_wire;

      if (mc->molecule_size > mc->no_label_threshold)
        do_labels = 0;
      if (mc->molecule_size > mc->wireframe_threshold)
        cur_wire = 1;

      if (cur_wire)
        do_bonds = 1;

      build_molecule (mi);

      glEndList();
    }
 SKIP:

  glPushMatrix ();
  glScalef(1.1, 1.1, 1.1);

  {
    GLfloat x, y, z;

    if (do_wander)
      {
        static int frame = 0;

#       define SINOID(SCALE,SIZE) \
        ((((1 + sin((frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2)

        x = SINOID(0.031, 9.0);
        y = SINOID(0.023, 9.0);
        z = SINOID(0.017, 9.0);
        frame++;
        glTranslatef(x, y, z);
      }

    if (mc->spin_x || mc->spin_y || mc->spin_z)
      {
        x = mc->rotx;
        y = mc->roty;
        z = mc->rotz;
        if (x < 0) x = 1 - (x + 1);
        if (y < 0) y = 1 - (y + 1);
        if (z < 0) z = 1 - (z + 1);

        if (mc->spin_x) glRotatef(x * 360, 1.0, 0.0, 0.0);
        if (mc->spin_y) glRotatef(y * 360, 0.0, 1.0, 0.0);
        if (mc->spin_z) glRotatef(z * 360, 0.0, 0.0, 1.0);

        rotate(&mc->rotx, &mc->dx, &mc->ddx, mc->d_max, MI_IS_VERBOSE(mi));
        rotate(&mc->roty, &mc->dy, &mc->ddy, mc->d_max, MI_IS_VERBOSE(mi));
        rotate(&mc->rotz, &mc->dz, &mc->ddz, mc->d_max, MI_IS_VERBOSE(mi));
      }
  }

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glCallList (mc->molecule_dlist);
  glPopMatrix ();

  if (MI_IS_FPS(mi)) do_fps (mi);
  glFinish();

  glXSwapBuffers(dpy, window);
}
Example #12
0
void
getImage(ModeInfo * mi, XImage ** logo,
	 int default_width, int default_height, unsigned char *default_bits,
#ifdef HAVE_XPM
	 int default_xpm, char **name,
#endif
	 int *graphics_format, Colormap * ncm,
	 unsigned long *black)
{
	Display    *display = MI_DISPLAY(mi);
	static char *bitmap_local = (char *) NULL;

#ifndef STANDALONE
#ifdef HAVE_XPM
	XpmAttributes attrib;

#endif
#if 0
	/* This probably works best in most cases but for random mode used
	   with random selection of a file it will fail often. */
	*ncm = None;
#else
	if (!fixedColors(mi))
		*ncm = XCreateColormap(display, MI_WINDOW(mi), MI_VISUAL(mi), AllocNone);
	else
		*ncm = None;
#endif
#ifdef HAVE_XPM
	attrib.visual = MI_VISUAL(mi);
	if (*ncm == None) {
		attrib.colormap = MI_COLORMAP(mi);
	} else {
		attrib.colormap = *ncm;
	}
	attrib.depth = MI_DEPTH(mi);
	attrib.valuemask = XpmVisual | XpmColormap | XpmDepth;
#endif
#endif /* !STANDALONE */
	*graphics_format = 0;

	if (bitmap_local != NULL) {
		free(bitmap_local);
		bitmap_local = (char *) NULL;
	}
	if (MI_BITMAP(mi) && strlen(MI_BITMAP(mi))) {
#ifdef STANDALONE
		bitmap_local = MI_BITMAP(mi);
#else
		if ((bitmap_local = (char *) malloc(256)) == NULL) {
			(void) fprintf(stderr , "no memory for \"%s\"\n" ,
				MI_BITMAP(mi));
			return;
		}
		(void) strncpy(bitmap_local, MI_BITMAP(mi), 256);
#if HAVE_DIRENT_H
		getRandomFile(MI_BITMAP(mi), bitmap_local);
#endif
#endif /* STANDALONE */
	}
	if (bitmap_local && strlen(bitmap_local)) {
#if defined( USE_MAGICK ) && !defined( STANDALONE )
	   if ( readable( bitmap_local ) )
	     {
		if ( MI_NPIXELS( mi ) > 2 )
		  {
		     Colormap magick_colormap;
		     if (*ncm == None) {
			magick_colormap = MI_COLORMAP(mi);
		     } else {
			magick_colormap = *ncm;
		     }
		     if ( MagickSuccess == MagickFileToImage( mi ,
							     bitmap_local ,
							     logo ,
							      magick_colormap 
							      ) )
		       {
			  *graphics_format = IS_MAGICKFILE;
			  *black = GetColor(mi, MI_BLACK_PIXEL(mi));
			  (void) GetColor(mi, MI_WHITE_PIXEL(mi));
			  (void) GetColor(mi, MI_BG_PIXEL(mi));
			  (void) GetColor(mi, MI_FG_PIXEL(mi));
		       }
		  }
	     }
	   else
	     {
		(void) fprintf(stderr , "could not read file \"%s\"\n" ,
			bitmap_local);
	     }
#else
# ifndef STANDALONE
		if (readable(bitmap_local)) {
			if (MI_NPIXELS(mi) > 2) {
			   Colormap ras_colormap;
			   if (*ncm == None) {
			      ras_colormap = MI_COLORMAP(mi);
			   } else {
			      ras_colormap = *ncm;
			   }
				if (RasterSuccess == RasterFileToImage(mi,
					       bitmap_local, logo ,
					       ras_colormap )) {
					*graphics_format = IS_RASTERFILE;
					*black = GetColor(mi, MI_BLACK_PIXEL(mi));
					(void) GetColor(mi, MI_WHITE_PIXEL(mi));
					(void) GetColor(mi, MI_BG_PIXEL(mi));
					(void) GetColor(mi, MI_FG_PIXEL(mi));
				}
			}
		} else {
			(void) fprintf(stderr,
			       "could not read file \"%s\"\n", bitmap_local);
		}
#ifdef HAVE_XPM
#ifndef USE_MONOXPM
		if (MI_NPIXELS(mi) > 2)
#endif
		{
			if (*graphics_format <= 0) {
				if (*ncm != None)
					reserveColors(mi, *ncm, black);
				if (XpmSuccess == XpmReadFileToImage(display,
				      bitmap_local, logo,
				      (XImage **) NULL, &attrib))
					*graphics_format = IS_XPMFILE;
			}
		}
#endif
#endif /* !STANDALONE */
		if (*graphics_format <= 0) {
			if (!blogo.data) {
				if (BitmapSuccess == XbmReadFileToImage(bitmap_local,
						 &blogo.width, &blogo.height,
					   (unsigned char **) &blogo.data)) {
					blogo.bytes_per_line = (blogo.width + 7) / 8;
					*graphics_format = IS_XBMFILE;
					*logo = &blogo;
				}
			} else {
				*graphics_format = IS_XBMDONE;
				*logo = &blogo;
			}
		}
#endif
	   if (*graphics_format <= 0 && MI_IS_VERBOSE(mi))
			(void) fprintf(stderr,
				       "\"%s\" is in an unrecognized format or not compatible with screen\n",
				       bitmap_local);
	}
#ifndef STANDALONE
#ifdef HAVE_XPM
	if (*graphics_format <= 0 &&
	    ((MI_IS_FULLRANDOM(mi)) ? LRAND() & 1: default_xpm))
#ifndef USE_MONOXPM
		if (MI_NPIXELS(mi) > 2)
#endif
			if (XpmSuccess == XpmCreateImageFromData(display, name,
					    logo, (XImage **) NULL, &attrib))
				*graphics_format = IS_XPM;
#endif
#endif /* STANDALONE */
	if (*graphics_format <= 0) {
		if (!blogo.data) {
			blogo.data = (char *) default_bits;
			blogo.width = default_width;
			blogo.height = default_height;
			blogo.bytes_per_line = (blogo.width + 7) / 8;
			*graphics_format = IS_XBM;
		} else
			*graphics_format = IS_XBMDONE;
		*logo = &blogo;
	}
#ifndef STANDALONE		/* Come back later */
	if (*ncm != None && *graphics_format != IS_RASTERFILE &&
	    *graphics_format != IS_XPMFILE && *graphics_format != IS_XPM &&
	    *graphics_format != IS_MAGICKFILE) {
		XFreeColormap(display, *ncm);
		*ncm = None;
	}
#endif	/* STANDALONE */ /* Come back later */
}
Example #13
0
void init_xcl(ModeInfo * mi)
{
  Display *display = MI_DISPLAY(mi);
  int i;            /* scratch */
  xclstruct *dp;

  if (xcls == NULL) {
    if ((xcls = (xclstruct *) calloc(MI_NUM_SCREENS(mi),
                                     sizeof (xclstruct))) == NULL)
      return;
  }
  dp = &xcls[MI_SCREEN(mi)];

  /* Update every time */
  dp->width = MI_WIDTH(mi);
  dp->height = MI_HEIGHT(mi);
  dp->mid_x = (dp->width / 2);
  dp->mid_y = (dp->height / 2);

  if(dp->no_preset != 1) {
    dp->no_preset = 1;
    /* some presettings */
    dp->planes = MI_COUNT(mi);
    if (dp->planes < -MINPLANES) {
      dp->planes = NRAND(-MI_COUNT(mi) -MINPLANES + 1) + MINPLANES;
    } else if (dp->planes < MINPLANES) {
      dp->planes = MINPLANES;
    }
    if(dp->planes > MAXCOUNT)
      dp->planes = MAXCOUNT;
    dp->Alpha = 0.0;          /* rotate.1 */
    dp->Beta  = 0.0;          /* rotate.2 */
    dp->Gamma = 0.0;          /* rotate.3 */
    dp->Vx = 1;               /* width from zero in X */
    dp->Vy = 800;             /* width from zero in Y */
    dp->Vz = -300;            /* width from zero in Z */
    dp->G =  500.0;           /* ZOOM  */
    dp->time3 = 1.0;
    dp->drawtime = 25000;
    dp->xcldelay = STARTUPDELAY;
    for(i=0;i< dp->planes; i++) {
      dp->az[i] = 2 * M_PI * i / (float)((dp->planes));
      dp->el[i] = 0.0;
      dp->alpha[i] = 0.75;      /* direction */
      dp->turn[i] = 0;
      dp->turn_direction[i] = 1;

      speed[i] = speed_in;  /* see TODO */
    }

    random_pid = getpid(); /* goes here first for randomstart */

    if(randomstart) {
      for(i=0;i< dp->planes; i++) {
        switch(i) {
        case 0:
          dp->az[0] += (random_pid % 31) / 5.0;
          break;
        default:
          dp->az[i] = dp->az[0] + 2 * M_PI * i / (float)((dp->planes));
        }
      }
    }

    dp->bg = MI_BLACK_PIXEL(mi);

    if(MI_NPIXELS(mi) <= 2)
      for(i=0;i< dp->planes; i++) {
        dp->planecolor[i] = MI_WHITE_PIXEL(mi);
      }
    else {
      if(!oldcolor) {
        for(i=0;i< dp->planes; i++) {
          dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
        }
      }
      else { /* with count >2 no so good */
        for(i=0;i< dp->planes; i++) {
          switch(i) {
          case 0:
            dp->planecolor[0] = get_color(mi, (char *) "yellow",
		(XColor *) NULL);
            break;
          case 1:
            dp->planecolor[1] = get_color(mi, (char *) "red",
		(XColor *) NULL);
            break;
          default:
            dp->planecolor[i] = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
          }
        }
      }
    }

    if(dp->erase_gc == None)
      if (!get_GC(display, MI_WINDOW(mi), &(dp->erase_gc),dp->bg)) {
        free_xcl(display, dp);
        return;
      }

    dp->lines = countlines();

    for(i=0;i< dp->planes; i++) {
      if(dp->gc[i] == None)
        if (!get_GC(display, MI_WINDOW(mi), &(dp->gc[i]),
                    dp->planecolor[i])) {
          free_xcl(display, dp);
          return;
        }
      dp->omega_const[i] = speed[i]/3.6 /line_length*1000.0;

      if(dp->xseg[i] == NULL)
        if ((dp-> xseg[i] = (XSegment *) malloc(sizeof(XSegment) *
                                                dp->lines)) == NULL) {
          free_xcl(display, dp);
          return;
        }
      if(dp->xseg_old[i] == NULL)
        if ((dp->xseg_old[i] = (XSegment *) malloc(sizeof(XSegment) *
                                                   dp->lines)) == NULL) {
          free_xcl(display, dp);
          return;
        }
    }

    if(MI_IS_VERBOSE(mi)) {
      (void) printf("X control line combat in a box\n");
#if !defined( lint ) && !defined( SABER )
      (void) printf("Version: %s\n",sccsid);
#endif
      (void) printf("Line length: %gm\n",line_length/1000.0);
      (void) printf("Speed %g km/h  \n",speed[0]);
      (void) printf("Lines per plane: %d\n",dp->lines);
      (void) printf("Spectator at %gm\n",spectator/1000.0);
      (void) printf("Try %g frames per Second (frametime: %dus)\n",
                    1000000.0/frametime,frametime);
      (void) printf("Calibration at %d frames\n",REGULATE);
    }
  }

  /* clear the screen */

  MI_CLEARWINDOW(mi);

  (void) gettimeofday(&(dp->tv1),0);
  dp->time1 = (double)dp->tv1.tv_sec +
    (double)dp->tv1.tv_usec/(double)1000000;

  dp->xcldelay = frametime;
}
Example #14
0
/*-
 * Add a tile described by vtype to the side of vertex.  This must be
 * allowed by the rules -- we do not check it here.  New vertices are
 * allocated as necessary.  The fringe and the forced vertex pool are updated.
 * The new tile is drawn on the display.
 *
 * One thing we do check here is whether the new tile causes an untiled
 * area to become enclosed by the tiling.  If this would happen, the tile
 * is not added.  The return value is true iff a tile was added.
 */
static int
add_tile(ModeInfo * mi,
	 fringe_node_c * vertex, unsigned side, vertex_type_c vtype)
{
	tiling_c   *tp = &tilings[MI_SCREEN(mi)];

	fringe_node_c
		*left = (fringe_node_c *) NULL,
		*right = (fringe_node_c *) NULL,
		*far = (fringe_node_c *) NULL,
		*node;
	unsigned    fc = fringe_changes(mi, vertex, side, vtype, &right, &far, &left);

	vertex_type_c
		ltype = VT_LEFT(vtype),
		rtype = VT_RIGHT(vtype),
		ftype = VT_FAR(vtype);

	/* By our conventions vertex->next lies to the left of vertex and
	   vertex->prev to the right. */

	/* This should never occur. */
	if (fc & FC_BAG) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in add_tile()\n");
			(void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG);
		}
	}
	if (side == S_LEFT) {
		if (right == NULL)
			if ((right = alloc_vertex(mi, vertex_dir(mi, vertex, S_LEFT) -
					vtype_angle(vtype), vertex, tp)) == NULL)
				return False;
		if (far == NULL)
			if ((far = alloc_vertex(mi, vertex_dir(mi, left, S_RIGHT) +
					vtype_angle(ltype), left, tp)) == NULL)
				return False;
	} else {
		if (left == NULL)
			if ((left = alloc_vertex(mi, vertex_dir(mi, vertex, S_RIGHT) +
					vtype_angle(vtype), vertex, tp)) == NULL)
				return False;
		if (far == NULL)
			if ((far = alloc_vertex(mi, vertex_dir(mi, right, S_LEFT) -
					vtype_angle(rtype), right, tp)) == NULL)
				return False;
	}

	/* Having allocated the new vertices, but before joining them with
	   the rest of the fringe, check if vertices with same coordinates
	   already exist.  If any such are found, give up. */
	node = tp->fringe.nodes;
	do {
		if (((fc & FC_NEW_LEFT) && fived_equal(node->fived, left->fived))
		    || ((fc & FC_NEW_RIGHT) && fived_equal(node->fived, right->fived))
		    || ((fc & FC_NEW_FAR) && fived_equal(node->fived, far->fived))) {
			/* Better luck next time. */
			if (fc & FC_NEW_LEFT)
				delete_vertex(mi, left, tp);
			if (fc & FC_NEW_RIGHT)
				delete_vertex(mi, right, tp);
			if (fc & FC_NEW_FAR)
				delete_vertex(mi, far, tp);
			return False;
		}
		node = node->next;
	} while (node != tp->fringe.nodes);

	/* Rechain. */
	if (!(fc & FC_CUT_THIS)) {
		if (side == S_LEFT) {
			vertex->next = right;
			right->prev = vertex;
		} else {
			vertex->prev = left;
			left->next = vertex;
		}
	}
	if (!(fc & FC_CUT_FAR)) {
		if (!(fc & FC_CUT_LEFT)) {
			far->next = left;
			left->prev = far;
		}
		if (!(fc & FC_CUT_RIGHT)) {
			far->prev = right;
			right->next = far;
		}
	}
	draw_tile(vertex, right, far, left, vtype, mi);

	/* Delete vertices that are no longer on the fringe.  Check the others. */
	if (fc & FC_CUT_THIS) {
		tp->fringe.nodes = far;
		delete_vertex(mi, vertex, tp);
	} else {
		add_vtype(vertex, side, vtype);
		check_vertex(mi, vertex, tp);
		tp->fringe.nodes = vertex;
	}
	if (fc & FC_CUT_FAR)
		delete_vertex(mi, far, tp);
	else {
		add_vtype(far, fc & FC_CUT_RIGHT ? S_LEFT : S_RIGHT, ftype);
		check_vertex(mi, far, tp);
	}
	if (fc & FC_CUT_LEFT)
		delete_vertex(mi, left, tp);
	else {
		add_vtype(left, fc & FC_CUT_FAR ? S_LEFT : S_RIGHT, ltype);
		check_vertex(mi, left, tp);
	}
	if (fc & FC_CUT_RIGHT)
		delete_vertex(mi, right, tp);
	else {
		add_vtype(right, fc & FC_CUT_FAR ? S_RIGHT : S_LEFT, rtype);
		check_vertex(mi, right, tp);
	}
	return True;
}
Example #15
0
void
make_smooth_colormap(ModeInfo * mi, Colormap cmap,
		     XColor * colors, int *ncolorsP,
		     Bool allocate_p,
		     Bool * writable_pP)
{
	int         npoints;
	int         ncolors = *ncolorsP;
	Bool        wanted_writable = (allocate_p && writable_pP && *writable_pP);
	int         i;
	int         h[MAXPOINTS];
	double      s[MAXPOINTS];
	double      v[MAXPOINTS];
	double      total_s = 0;
	double      total_v = 0;

	if (*ncolorsP <= 0)
		return;

	{
		int         n = (int) (LRAND() % 20);

		if (n <= 5)
			npoints = 2;	/* 30% of the time */
		else if (n <= 15)
			npoints = 3;	/* 50% of the time */
		else if (n <= 18)
			npoints = 4;	/* 15% of the time */
		else
			npoints = 5;	/*  5% of the time */
	}

      REPICK_ALL_COLORS:
	for (i = 0; i < npoints; i++) {
	      REPICK_THIS_COLOR:
		h[i] = (int) (LRAND() % 360);
		s[i] = LRAND() / MAXRAND;
		v[i] = 0.8 * LRAND() / MAXRAND + 0.2;

		/* Make sure that no two adjascent colors are *too* close together.
		   If they are, try again.
		 */
		if (i > 0) {
			int         j = (i + 1 == npoints) ? 0 : (i - 1);
			double      hi = ((double) h[i]) / 360;
			double      hj = ((double) h[j]) / 360;
			double      dh = hj - hi;
			double      distance;

			if (dh < 0)
				dh = -dh;
			if (dh > 0.5)
				dh = 0.5 - (dh - 0.5);
			distance = sqrt((dh * dh) +
					((s[j] - s[i]) * (s[j] - s[i])) +
					((v[j] - v[i]) * (v[j] - v[i])));
			if (distance < 0.2)
				goto REPICK_THIS_COLOR;
		}
		total_s += s[i];
		total_v += v[i];
	}

	/* If the average saturation or intensity are too low, repick the colors,
	   so that we don't end up with a black-and-white or too-dark map.
	 */
	if (total_s / npoints < 0.2)
		goto REPICK_ALL_COLORS;
	if (total_v / npoints < 0.3)
		goto REPICK_ALL_COLORS;

	/* If this visual doesn't support writable cells, don't bother trying.
	 */
	if (wanted_writable && !has_writable_cells(mi))
		*writable_pP = False;

      RETRY_NON_WRITABLE:
	make_color_path(MI_DISPLAY(mi), cmap, npoints, h, s, v, colors, &ncolors,
			allocate_p, (writable_pP && *writable_pP));

	/* If we tried for writable cells and got none, try for non-writable. */
	if (allocate_p && *ncolorsP == 0 && *writable_pP) {
		*writable_pP = False;
		goto RETRY_NON_WRITABLE;
	}
	if (MI_IS_VERBOSE(mi) || MI_IS_DEBUG(mi))
		complain(*ncolorsP, ncolors, wanted_writable,
			 wanted_writable && *writable_pP);

	*ncolorsP = ncolors;
}
Example #16
0
void
make_random_colormap(ModeInfo * mi, Colormap cmap,
		     XColor * colors, int *ncolorsP,
		     Bool bright_p,
		     Bool allocate_p,
		     Bool * writable_pP)
{
	Bool        wanted_writable = (allocate_p && writable_pP && *writable_pP);
	int         ncolors = *ncolorsP;
	int         i;

	if (*ncolorsP <= 0)
		return;

	/* If this visual doesn't support writable cells, don't bother trying. */
	if (wanted_writable && !has_writable_cells(mi))
		*writable_pP = False;

	for (i = 0; i < ncolors; i++) {
		colors[i].flags = DoRed | DoGreen | DoBlue;
		if (bright_p) {
			int         H = (int) LRAND() % 360;	/* range 0-360    */
			double      S = ((double) (LRAND() % 70) + 30) / 100.0;		/* range 30%-100% */
			double      V = ((double) (LRAND() % 34) + 66) / 100.0;		/* range 66%-100% */

			hsv_to_rgb(H, S, V,
			  &colors[i].red, &colors[i].green, &colors[i].blue);
		} else {
			colors[i].red = (unsigned short) (LRAND() % 0xFFFF);
			colors[i].green = (unsigned short) (LRAND() % 0xFFFF);
			colors[i].blue = (unsigned short) (LRAND() % 0xFFFF);
		}
	}

	if (!allocate_p)
		return;

      RETRY_NON_WRITABLE:
	if (writable_pP && *writable_pP) {
		unsigned long *pixels = (unsigned long *)
		malloc(sizeof (unsigned long) * (ncolors + 1));

		allocate_writable_colors(MI_DISPLAY(mi), cmap, pixels, &ncolors);
		if (ncolors > 0)
			for (i = 0; i < ncolors; i++)
				colors[i].pixel = pixels[i];
		free(pixels);
		if (ncolors > 0)
			XStoreColors(MI_DISPLAY(mi), cmap, colors, ncolors);
	} else {
		for (i = 0; i < ncolors; i++) {
			XColor      color;

			color = colors[i];
			if (!XAllocColor(MI_DISPLAY(mi), cmap, &color))
				break;
			colors[i].pixel = color.pixel;
		}
		ncolors = i;
	}

	/* If we tried for writable cells and got none, try for non-writable. */
	if (allocate_p && ncolors == 0 && writable_pP && *writable_pP) {
		ncolors = *ncolorsP;
		*writable_pP = False;
		goto RETRY_NON_WRITABLE;
	}
	if (MI_IS_VERBOSE(mi) || MI_IS_DEBUG(mi))
		complain(*ncolorsP, ncolors, wanted_writable,
			 wanted_writable && *writable_pP);

	*ncolorsP = ncolors;
}
Example #17
0
/* Called to init the mode. */
void
init_penrose(ModeInfo * mi)
{
	tiling_c   *tp;
	fringe_node_c *fp;
	int         i, size;

	if (tilings == NULL) {
		if ((tilings = (tiling_c *) calloc(MI_NUM_SCREENS(mi),
						 sizeof (tiling_c))) == NULL)
			return;
	}
	tp = &tilings[MI_SCREEN(mi)];

	if (MI_IS_FULLRANDOM(mi))
		tp->ammann = (Bool) (LRAND() & 1);
	else
		tp->ammann = ammann;
	tp->done = False;
	tp->busyLoop = 0;
	tp->failures = 0;
	tp->width = MI_WIDTH(mi);
	tp->height = MI_HEIGHT(mi);
	if (MI_NPIXELS(mi) > 2) {
		tp->thick_color = NRAND(MI_NPIXELS(mi));
		/* Insure good contrast */
		tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color +
				  MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi);
	} else {
		if (LRAND() & 1) {
			tp->thick_color = MI_WHITE_PIXEL(mi);
			tp->thin_color = MI_BLACK_PIXEL(mi);
		} else {
			tp->thick_color = MI_BLACK_PIXEL(mi);
			tp->thin_color = MI_WHITE_PIXEL(mi);
		}
	}
	size = MI_SIZE(mi);
	if (size < -MINSIZE)
		tp->edge_length = NRAND(MIN(-size, MAX(MINSIZE,
		   MIN(tp->width, tp->height) / 2)) - MINSIZE + 1) + MINSIZE;
	else if (size < MINSIZE) {
		if (!size)
			tp->edge_length = MAX(MINSIZE, MIN(tp->width, tp->height) / 2);
		else
			tp->edge_length = MINSIZE;
	} else
		tp->edge_length = MIN(size, MAX(MINSIZE,
					    MIN(tp->width, tp->height) / 2));
	tp->origin.x = (tp->width / 2 + NRAND(tp->width)) / 2;
	tp->origin.y = (tp->height / 2 + NRAND(tp->height)) / 2;
	tp->fringe.n_nodes = 2;
	if (tp->fringe.nodes != NULL)
		free_penrose(tp);
	if (tp->fringe.nodes != NULL || tp->forced.first != 0) {
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in init_penrose()\n");
			(void) fprintf(stderr, "tp->fringe.nodes = NULL && tp->forced.first = 0\n");
		}
		free_penrose(tp);	/* Try again */
		tp->done = True;
	}
	tp->forced.n_nodes = tp->forced.n_visible = 0;
	if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) {
		free_penrose(tp);
		return;
	}
	if (fp == 0) {
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in init_penrose()\n");
			(void) fprintf(stderr, "fp = 0\n");
		}
		if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) {
			free_penrose(tp);
			return;
		}
		tp->done = True;
	}
	/* First vertex. */
	fp->rule_mask = (1 << N_VERTEX_RULES) - 1;
	fp->list_ptr = 0;
	if  ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) {
		free_penrose(tp);
		return;
	}
	if (fp->next == 0) {
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in init_penrose()\n");
			(void) fprintf(stderr, "fp->next = 0\n");
		}
		if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) {
			free_penrose(tp);
			return;
		}
		tp->done = True;
	}
	fp->n_tiles = 0;
	fp->loc = tp->origin;
	fp->off_screen = False;
	for (i = 0; i < 5; i++)
		fp->fived[i] = 0;

	/* Second vertex. */
	*(fp->next) = *fp;
	fp->next->prev = fp->next->next = fp;
	fp = fp->next;
	i = NRAND(5);
	fp->fived[i] = 2 * NRAND(2) - 1;
	fived_to_loc(fp->fived, tp, &(fp->loc));
	/* That's it!  We have created our first edge. */
}
Example #18
0
void
init_wire(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	int         i, size = MI_SIZE(mi), n;
	circuitstruct *wp;
	XGCValues   gcv;

	if (circuits == NULL) {
		if ((circuits = (circuitstruct *) calloc(MI_NUM_SCREENS(mi),
					    sizeof (circuitstruct))) == NULL)
			return;
	}
	wp = &circuits[MI_SCREEN(mi)];

	wp->redrawing = 0;

	if ((MI_NPIXELS(mi) <= 2) && (wp->init_bits == 0)) {
		if (wp->stippledGC == None) {
			gcv.fill_style = FillOpaqueStippled;
			if ((wp->stippledGC = XCreateGC(display, window, GCFillStyle,
					&gcv)) == None) {
				free_wire(display, wp);
				return;
			}
		}
		WIREBITS(stipples[NUMSTIPPLES - 1], STIPPLESIZE, STIPPLESIZE);
		WIREBITS(stipples[NUMSTIPPLES - 3], STIPPLESIZE, STIPPLESIZE);
		WIREBITS(stipples[2], STIPPLESIZE, STIPPLESIZE);
	}
	if (MI_NPIXELS(mi) > 2) {
		wp->colors[0] = (NRAND(MI_NPIXELS(mi)));
		wp->colors[1] = (wp->colors[0] + MI_NPIXELS(mi) / 6 +
			     NRAND(MI_NPIXELS(mi) / 4 + 1)) % MI_NPIXELS(mi);
		wp->colors[2] = (wp->colors[1] + MI_NPIXELS(mi) / 6 +
			     NRAND(MI_NPIXELS(mi) / 4 + 1)) % MI_NPIXELS(mi);
	}
	free_list(wp);
	wp->generation = 0;
	if (MI_IS_FULLRANDOM(mi)) {
		wp->vertical = (Bool) (LRAND() & 1);
	} else {
		wp->vertical = vertical;
	}
	wp->width = MI_WIDTH(mi);
	wp->height = MI_HEIGHT(mi);

	for (i = 0; i < NEIGHBORKINDS; i++) {
		if (neighbors == plots[i]) {
			wp->neighbors = plots[i];
			break;
		}
		if (i == NEIGHBORKINDS - 1) {
			i = NRAND(NEIGHBORKINDS - 3) + 1;	/* Skip triangular ones */
			wp->neighbors = plots[i];
			break;
		}
	}

	wp->prob_array[wp->neighbors - 1] = 100;
	if (wp->neighbors == 3) {
		wp->prob_array[1] = 67;
		wp->prob_array[0] = 33;
	} else {
		int         incr = 24 / wp->neighbors;

		for (i = wp->neighbors - 2; i >= 0; i--) {
			wp->prob_array[i] = wp->prob_array[i + 1] - incr -
				incr * ((i + 1) != wp->neighbors / 2);
		}
	}

	if (wp->neighbors == 6) {
		int  nccols, ncrows;

		wp->polygon = 6;
		if (!wp->vertical) {
			wp->height = MI_WIDTH(mi);
			wp->width = MI_HEIGHT(mi);
		}
		if (wp->width < 8)
			wp->width = 8;
		if (wp->height < 8)
			wp->height = 8;
		if (size < -MINSIZE)
			wp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(wp->width, wp->height) /
				      MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
		else if (size < MINSIZE) {
			if (!size)
				wp->ys = MAX(MINSIZE, MIN(wp->width, wp->height) / MINGRIDSIZE);
			else
				wp->ys = MINSIZE;
		} else
			wp->ys = MIN(size, MAX(MINSIZE, MIN(wp->width, wp->height) /
					       MINGRIDSIZE));
		wp->xs = wp->ys;
		nccols = MAX(wp->width / wp->xs - 2, 16);
		ncrows = MAX(wp->height / wp->ys - 1, 16);
		wp->ncols = nccols / 2;
		wp->nrows = ncrows / 2;
		wp->nrows -= !(wp->nrows & 1);	/* Must be odd */
		wp->xb = (wp->width - wp->xs * nccols) / 2 + wp->xs;
		wp->yb = (wp->height - wp->ys * ncrows) / 2 + wp->ys;
		for (i = 0; i < 6; i++) {
			if (wp->vertical) {
				wp->shape.hexagon[i].x =
					(wp->xs - 1) * hexagonUnit[i].x;
				wp->shape.hexagon[i].y =
					((wp->ys - 1) * hexagonUnit[i].y /
					2) * 4 / 3;
			} else {
				wp->shape.hexagon[i].y =
					(wp->xs - 1) * hexagonUnit[i].x;
				wp->shape.hexagon[i].x =
					((wp->ys - 1) * hexagonUnit[i].y /
					2) * 4 / 3;
			}
		}
	} else if (wp->neighbors == 4 || wp->neighbors == 8) {
		wp->polygon = 4;
		if (size < -MINSIZE)
			wp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(wp->width, wp->height) /
				      MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
		else if (size < MINSIZE) {
			if (!size)
				wp->ys = MAX(MINSIZE, MIN(wp->width, wp->height) / MINGRIDSIZE);
			else
				wp->ys = MINSIZE;
		} else
			wp->ys = MIN(size, MAX(MINSIZE, MIN(wp->width, wp->height) /
					       MINGRIDSIZE));
		wp->xs = wp->ys;
		wp->ncols = MAX(wp->width / wp->xs, 8);
		wp->nrows = MAX(wp->height / wp->ys, 8);
		wp->xb = (wp->width - wp->xs * wp->ncols) / 2;
		wp->yb = (wp->height - wp->ys * wp->nrows) / 2;
	} else {		/* TRI */
		int orient;

		wp->polygon = 3;
		if (!wp->vertical) {
			wp->height = MI_WIDTH(mi);
			wp->width = MI_HEIGHT(mi);
		}
		if (wp->width < 4)
			wp->width = 4;
		if (wp->height < 2)
			wp->height = 2;
		if (size < -MINSIZE)
			wp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(wp->width, wp->height) /
				      MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
		else if (size < MINSIZE) {
			if (!size)
				wp->ys = MAX(MINSIZE, MIN(wp->width, wp->height) / MINGRIDSIZE);
			else
				wp->ys = MINSIZE;
		} else
			wp->ys = MIN(size, MAX(MINSIZE, MIN(wp->width, wp->height) /
					       MINGRIDSIZE));
		wp->xs = (int) (1.52 * wp->ys);
		wp->ncols = (MAX(wp->width / wp->xs - 1, 8) / 2) * 2;
		wp->nrows = (MAX(wp->height / wp->ys - 1, 8) / 2) * 2 - 1;
		wp->xb = (wp->width - wp->xs * wp->ncols) / 2 + wp->xs / 2;
		wp->yb = (wp->height - wp->ys * wp->nrows) / 2 + wp->ys;
		for (orient = 0; orient < 2; orient++) {
			for (i = 0; i < 3; i++) {
				if (wp->vertical) {
					wp->shape.triangle[orient][i].x =
						(wp->xs - 2) * triangleUnit[orient][i].x;
					wp->shape.triangle[orient][i].y =
						(wp->ys - 2) * triangleUnit[orient][i].y;
				} else {
					wp->shape.triangle[orient][i].y =
						(wp->xs - 2) * triangleUnit[orient][i].x;
					wp->shape.triangle[orient][i].x =
						(wp->ys - 2) * triangleUnit[orient][i].y;
				}
			}
		}
	}

	/*
	 * I am being a bit naughty here wasting a little bit of memory
	 * but it will give me a real headache to figure out the logic
	 * and to refigure the mappings to save a few bytes
	 * ncols should only need a border of 2 and nrows should only need
	 * a border of 4 when in the neighbors = 9 or 12
	 */
	wp->bncols = wp->ncols + 4;
	wp->bnrows = wp->nrows + 4;

	if (MI_IS_VERBOSE(mi))
		(void) fprintf(stdout,
			"neighbors %d, ncols %d, nrows %d\n",
			wp->neighbors, wp->ncols, wp->nrows);
	MI_CLEARWINDOW(mi);

	if (wp->oldcells != NULL) {
		free(wp->oldcells);
		wp->oldcells = (unsigned char *) NULL;
	}
	if ((wp->oldcells = (unsigned char *) calloc(wp->bncols * wp->bnrows,
			sizeof (unsigned char))) == NULL) {
		free_wire(display, wp);
		return;
	}

	if (wp->newcells != NULL) {
		free(wp->newcells);
		wp->newcells = (unsigned char *) NULL;
	}
	if ((wp->newcells = (unsigned char *) calloc(wp->bncols * wp->bnrows,
			sizeof (unsigned char))) == NULL) {
		free_wire(display, wp);
		return;
	}

	n = MI_COUNT(mi);
	i = (1 + (wp->neighbors == 6)) * wp->ncols * wp->nrows / 4;
	if (n < -MINWIRES && i > MINWIRES) {
		n = NRAND(MIN(-n, i) - MINWIRES + 1) + MINWIRES;
	} else if (n < MINWIRES) {
		n = MINWIRES;
	} else if (n > i) {
		n = MAX(MINWIRES, i);
	}
	create_path(wp, n);
}
Example #19
0
/*-
 * Add a randomly chosen tile to a given vertex.  This requires more checking
 * as we must make sure the new tile conforms to the vertex rules at every
 * vertex it touches. */
static void
add_random_tile(fringe_node_c * vertex, ModeInfo * mi)
{
	fringe_node_c *right, *left, *far;
	int         i, j, n, n_hits, n_good;
	unsigned    side, fc, no_good, s;
	vertex_type_c vtypes[MAX_COMPL];
	rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
	tiling_c   *tp = &tilings[MI_SCREEN(mi)];

	if (MI_NPIXELS(mi) > 2) {
		tp->thick_color = NRAND(MI_NPIXELS(mi));
		/* Insure good contrast */
		tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color +
				  MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi);
	} else {
		unsigned long temp = tp->thick_color;

		tp->thick_color = tp->thin_color;
		tp->thin_color = temp;
	}
	n_hits = match_rules(vertex, hits, False);
	side = NRAND(2) ? S_LEFT : S_RIGHT;
	n = find_completions(vertex, hits, n_hits, side, vtypes /*, False */ );
	/* One answer would mean a forced tile. */
	if (n <= 0) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in add_random_tile()\n");
			(void) fprintf(stderr, "n = %d\n", n);
		}
	}
	no_good = 0;
	n_good = n;
	for (i = 0; i < n; i++) {
		fc = fringe_changes(mi, vertex, side, vtypes[i], &right, &far, &left);
		if (fc & FC_BAG) {
			tp->done = True;
			if (MI_IS_VERBOSE(mi)) {
				(void) fprintf(stderr, "Weirdness in add_random_tile()\n");
				(void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG);
			}
		}
		if (right) {
			s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_LEFT)) ? S_RIGHT : S_LEFT);
			if (!legal_move(right, s, VT_RIGHT(vtypes[i]))) {
				no_good |= (1 << i);
				n_good--;
				continue;
			}
		}
		if (left) {
			s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_RIGHT)) ? S_LEFT : S_RIGHT);
			if (!legal_move(left, s, VT_LEFT(vtypes[i]))) {
				no_good |= (1 << i);
				n_good--;
				continue;
			}
		}
		if (far) {
			s = ((fc & FC_CUT_LEFT) ? S_RIGHT : S_LEFT);
			if (!legal_move(far, s, VT_FAR(vtypes[i]))) {
				no_good |= (1 << i);
				n_good--;
			}
		}
	}
	if (n_good <= 0) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in add_random_tile()\n");
			(void) fprintf(stderr, "n_good = %d\n", n_good);
		}
	}
	n = NRAND(n_good);
	for (i = j = 0; i <= n; i++, j++)
		while (no_good & (1 << j))
			j++;

	if (!add_tile(mi, vertex, side, vtypes[j - 1])) {
		tp->done = True;
		if (MI_IS_VERBOSE(mi)) {
			(void) fprintf(stderr, "Weirdness in add_random_tile()\n");
		}
		free_penrose(tp);
	}
}
Example #20
0
ENTRYPOINT void
init_flow (ModeInfo * mi)
{
	flowstruct *sp;
	char       *name;
	
	if (flows == NULL) {
		if ((flows = (flowstruct *) calloc(MI_NUM_SCREENS(mi),
										   sizeof (flowstruct))) == NULL)
			return;
	}
	sp = &flows[MI_SCREEN(mi)];

	sp->count2 = 0;

	sp->taillen = MI_SIZE(mi);
	if (sp->taillen < -MINTRAIL) {
		/* Change by sqrt so it seems more variable */
		sp->taillen = NRAND((int)sqrt((double) (-sp->taillen - MINTRAIL + 1)));
		sp->taillen = sp->taillen * sp->taillen + MINTRAIL;
	} else if (sp->taillen < MINTRAIL) {
		sp->taillen = MINTRAIL;
	}

	if(!rotatep && !ridep) rotatep = True; /* We need at least one viewpoint */

	/* Start camera at Orbit or Bee */
	if(rotatep) {
		sp->chaseto = ORBIT;
	} else {
		sp->chaseto = BEE;
	}
	sp->chasetime = 1; /* Go directly to target */

	sp->lyap = 0;
	sp->yperiod = 0;
	sp->step2 = INITIALSTEP;

	/* Zero parameter set */
	memset(sp->par2, 0, N_PARS * sizeof(dvector));

	/* Set up standard examples */
	switch (NRAND((periodicp) ? 5 : 3)) {
	case 0:
		/*
		  x' = a(y - x)
		  y' = x(b - z) - y
		  z' = xy - cz
		 */
		name = "Lorentz";
		sp->par2[Y].x = 10 + balance_rand(5*0); /* a */
		sp->par2[X].x = - sp->par2[Y].x;        /* -a */
		sp->par2[X].y = 28 + balance_rand(5*0); /* b */
		sp->par2[XZ].y = -1;
		sp->par2[Y].y = -1;
		sp->par2[XY].z = 1;
		sp->par2[Z].z = - 2 + balance_rand(1*0); /* -c */		
		break;
	case 1:
		/*
		  x' = -(y + az)
		  y' = x + by
		  z' = c + z(x - 5.7)
		 */
		name = "Rossler";
		sp->par2[Y].x = -1;
		sp->par2[Z].x = -2 + balance_rand(1); /* a */
		sp->par2[X].y = 1;
		sp->par2[Y].y = 0.2 + balance_rand(0.1); /* b */
		sp->par2[C].z = 0.2 + balance_rand(0.1); /* c */
		sp->par2[XZ].z = 1;
		sp->par2[Z].z = -5.7;
		break;
	case 2: 
		/*
		  x' = -(y + az)
		  y' = x + by - cz^2
		  z' = 0.2 + z(x - 5.7)
		 */
		name = "RosslerCone";
		sp->par2[Y].x = -1;
		sp->par2[Z].x = -2; /* a */
		sp->par2[X].y = 1;
		sp->par2[Y].y = 0.2; /* b */
		sp->par2[ZZ].y = -0.331 + balance_rand(0.01); /* c */
		sp->par2[C].z = 0.2;
		sp->par2[XZ].z = 1;
		sp->par2[Z].z = -5.7;
		break;
	case 3:
		/*
		  x' = -z + b sin(y)
		  y' = c
		  z' = 0.7x + az(0.1 - x^2) 
		 */
		name = "Birkhoff";
		sp->par2[Z].x = -1;
		sp->par2[SINY].x = 0.35 + balance_rand(0.25); /* b */
		sp->par2[C].y = 1.57; /* c */
		sp->par2[X].z = 0.7;
		sp->par2[Z].z = 1 + balance_rand(0.5); /* a/10 */
		sp->par2[XXZ].z = -10 * sp->par2[Z].z; /* -a */
		sp->yperiod = 2 * M_PI;
		break;
	default:
		/*
		  x' = -ax - z/2 - z^3/8 + b sin(y)
		  y' = c
		  z' = 2x
		 */
		name = "Duffing";
		sp->par2[X].x = -0.2 + balance_rand(0.1); /* a */
		sp->par2[Z].x = -0.5;
		sp->par2[ZZZ].x = -0.125;
		sp->par2[SINY].x = 27.0 + balance_rand(3.0); /* b */
		sp->par2[C].y = 1.33; /* c */
		sp->par2[X].z = 2;
		sp->yperiod = 2 * M_PI;
		break;

	}

	sp->range.x = 5;
	sp->range.z = 5;

	if(sp->yperiod > 0) {
		sp->ODE = Periodic;
		/* periodic flows show either uniform distribution or a
           snapshot on the 'time' axis */
		sp->range.y = NRAND(2)? sp->yperiod : 0;
	} else {
		sp->range.y = 5;
		sp->ODE = Cubic;
	}

	/* Run discoverer to set up bounding box, etc.  Lyapunov will
	   probably be innaccurate, since we're only running it once, but
	   we're using known strange attractors so it should be ok. */
	discover(mi);
	if(MI_IS_VERBOSE(mi))
		fprintf(stdout,
				"flow: Lyapunov exponent: %g, step: %g, size: %g (%s)\n",
				sp->lyap2, sp->step2, sp->size2, name);
	/* Install new params */
	sp->lyap = sp->lyap2;
	sp->size = sp->size2;
	sp->mid = sp->mid2;
	sp->step = sp->step2;
	memcpy(sp->par, sp->par2, sizeof(sp->par2));

	sp->count2 = 0; /* Reset search */

	free_flow(sp);
	sp->beecount = MI_COUNT(mi);
	if (sp->beecount < 0) {	/* random variations */
		sp->beecount = NRAND(-sp->beecount) + 1; /* Minimum 1 */
	}

# ifdef HAVE_COCOA	/* Don't second-guess Quartz's double-buffering */
  dbufp = False;
# endif

	if(dbufp) { /* Set up double buffer */
		if (sp->buffer != None)
			XFreePixmap(MI_DISPLAY(mi), sp->buffer);
		sp->buffer = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi),
								 MI_WIDTH(mi), MI_HEIGHT(mi), MI_DEPTH(mi));
	} else {
		sp->buffer = MI_WINDOW(mi);
	}
	/* no "NoExpose" events from XCopyArea wanted */
	XSetGraphicsExposures(MI_DISPLAY(mi), MI_GC(mi), False);

	/* Make sure we're using 'thin' lines */
	XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 0, LineSolid, CapNotLast,
					   JoinMiter);

	/* Clear the background (may be slow depending on user prefs). */
	MI_CLEARWINDOW(mi);

	/* Allocate memory. */
	if (sp->csegs == NULL) {
		allocate(sp->csegs, XSegment,
				 (sp->beecount + BOX_L) * MI_NPIXELS(mi) * sp->taillen);
		allocate(sp->cnsegs, int, MI_NPIXELS(mi));
		allocate(sp->old_segs, XSegment, sp->beecount * sp->taillen);
		allocate(sp->p, dvector, sp->beecount * sp->taillen);
	}
Example #21
0
void
draw_goop(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	int         i;
	goopstruct *gp;

	if (goops == NULL)
		return;
	gp = &goops[MI_SCREEN(mi)];
	if (gp->layers == NULL)
		return;

	MI_IS_DRAWN(mi) = True;
	switch (gp->mode) {
		case transparent:

			for (i = 0; i < gp->nlayers; i++)
				draw_layer_plane(display, &(gp->layers[i]), gp->width, gp->height);

			XSetForeground(display, gp->pixmap_gc, gp->background);
			XSetPlaneMask(display, gp->pixmap_gc, AllPlanes);
			XFillRectangle(display, gp->pixmap, gp->pixmap_gc, 0, 0,
				       gp->width, gp->height);
			XSetForeground(display, gp->pixmap_gc, ~0L);
			for (i = 0; i < gp->nlayers; i++) {
				XSetPlaneMask(display, gp->pixmap_gc, gp->layers[i].pixel);

#if 0
			XSetForeground (display, gp->pixmap_gc, ~0L);
			XFillRectangle (display, gp->pixmap, gp->pixmap_gc, 0, 0,
				gp->width, gp->height);
			XSetForeground (display, gp->pixmap_gc, 0L);
#endif
				draw_layer_blobs(display, gp->pixmap, gp->pixmap_gc,
				     &(gp->layers[i]), gp->width, gp->height,
						 True);
			}
			XCopyArea(display, gp->pixmap, window, MI_GC(mi), 0, 0,
				  gp->width, gp->height, 0, 0);
			break;

		case xored:
			XSetFunction(display, gp->pixmap_gc, GXcopy);
			XSetForeground(display, gp->pixmap_gc, 0);
			XFillRectangle(display, gp->pixmap, gp->pixmap_gc, 0, 0,
				       gp->width, gp->height);
			XSetFunction(display, gp->pixmap_gc, GXxor);
			XSetForeground(display, gp->pixmap_gc, 1);
			for (i = 0; i < gp->nlayers; i++)
				draw_layer_blobs(display, gp->pixmap, gp->pixmap_gc,
				     &(gp->layers[i]), gp->width, gp->height,
						 (gp->mode != outline));
			XCopyPlane(display, gp->pixmap, window, MI_GC(mi), 0, 0,
				   gp->width, gp->height, 0, 0, 1L);
			break;

		case opaque:
		case outline:
			XSetForeground(display, gp->pixmap_gc, MI_BLACK_PIXEL(mi));
			XFillRectangle(display, gp->pixmap, gp->pixmap_gc, 0, 0,
				       gp->width, gp->height);
			for (i = 0; i < gp->nlayers; i++) {
				XSetForeground(display, gp->pixmap_gc, gp->layers[i].pixel);
				draw_layer_blobs(display, gp->pixmap, gp->pixmap_gc,
				     &(gp->layers[i]), gp->width, gp->height,
						 (gp->mode != outline));
			}
			XCopyArea(display, gp->pixmap, window, MI_GC(mi), 0, 0,
				  gp->width, gp->height, 0, 0);
			break;

		default:
			if (MI_IS_VERBOSE(mi)) {
				(void) fprintf(stderr,
					"Weirdness in draw_goop()\n");
				(void) fprintf(stderr,
					"gp->mode = %d\n", gp->mode);
			}
			break;
	}
}