1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* discrete --- chaotic mappings */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)discrete.c 4.10 98/04/24 xlockmore";
10 * Copyright (c) 1996 by Tim Auckland <Tim.Auckland@Sun.COM>
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose and without fee is hereby granted,
14 * provided that the above copyright notice appear in all copies and that
15 * both that copyright notice and this permission notice appear in
16 * supporting documentation.
18 * This file is provided AS IS with no warranties of any kind. The author
19 * shall have no liability with respect to the infringement of copyrights,
20 * trade secrets or any patents by this file or any part thereof. In no
21 * event will the author be liable for any lost revenue or profits or
22 * other special, indirect and consequential damages.
24 * "discrete" shows a number of fractals based on the "discrete map"
25 * type of dynamical systems. They include a different way of looking
26 * at the HOPALONG system, an inverse julia-set iteration, the "Standard
27 * Map" and the "Bird in a Thornbush" fractal.
30 * 31-Jul-97: Ported to xlockmore-4
31 * 08-Aug-96: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton.
35 # define PROGCLASS "Discrete"
36 # define HACK_INIT init_discrete
37 # define HACK_DRAW draw_discrete
38 # define discrete_opts xlockmore_opts
39 # define SMOOTH_COLORS
40 # define BRIGHT_COLORS
41 # define DEFAULTS "*delay: 1000 \n" \
46 # include "xlockmore.h" /* in xscreensaver distribution */
49 #else /* STANDALONE */
50 # include "xlock.h" /* in xlockmore distribution */
51 #endif /* STANDALONE */
53 ModeSpecOpt discrete_opts =
54 {0, NULL, 0, NULL, NULL};
57 ModStruct discrete_description =
58 {"discrete", "init_discrete", "draw_discrete", "release_discrete",
59 "refresh_discrete", "init_discrete", NULL, &discrete_opts,
60 1000, 4096, 2500, 1, 64, 1.0, "",
61 "Shows various discrete maps", 0, NULL};
66 SQRT, BIRDIE, STANDARD, TRIG, CUBIC, HENON, AILUJ, HSHOE, DELOG
69 /*#define TEST STANDARD */
72 static int bias[BIASES] =
74 STANDARD, STANDARD, STANDARD, STANDARD,
75 SQRT, SQRT, SQRT, SQRT,
76 BIRDIE, BIRDIE, BIRDIE,
85 int maxy; /* max of the screen */
92 double j; /* discrete parameters */
101 XPoint *pointBuffer; /* pointer for XDrawPoints */
104 static discretestruct *discretes = NULL;
107 init_discrete(ModeInfo * mi)
112 if (discretes == NULL) {
114 (discretestruct *) calloc(MI_NUM_SCREENS(mi),
115 sizeof (discretestruct))) == NULL)
118 hp = &discretes[MI_SCREEN(mi)];
121 hp->maxx = MI_WIDTH(mi);
122 hp->maxy = MI_HEIGHT(mi);
126 hp->op = bias[LRAND() % BIASES];
132 hp->is = hp->maxx / (4);
133 hp->js = hp->maxy / (4);
144 hp->is = hp->maxx / 1.5;
145 hp->js = hp->maxy / 1.5;
147 hp->i = hp->j = 0.01;
150 hp->jc = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.4;
151 hp->ic = 1.3 * (1 - (hp->jc * hp->jc) / (0.4 * 0.4));
153 hp->js = hp->maxy * 1.5;
164 range = sqrt((double) hp->maxx * 2 * hp->maxx * 2 +
165 (double) hp->maxy * 2 * hp->maxy * 2) /
166 (10.0 + LRAND() % 10);
168 hp->a = (LRAND() / MAXRAND) * range - range / 2.0;
169 hp->b = (LRAND() / MAXRAND) * range - range / 2.0;
170 hp->c = (LRAND() / MAXRAND) * range - range / 2.0;
178 hp->is = hp->maxx / (M_PI * 2);
179 hp->js = hp->maxy / (M_PI * 2);
180 hp->a = 0; /* decay */
181 hp->b = (LRAND() / MAXRAND) * 2.0;
189 hp->is = hp->maxx / 2;
190 hp->js = hp->maxy / 2;
191 hp->a = 1.99 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.2;
193 hp->c = 0.8 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
198 hp->b = 0.5 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.3;
201 hp->is = hp->maxx / (hp->b * 20);
202 hp->js = hp->maxy / (hp->b * 20);
207 hp->b = 0.1 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
210 hp->is = hp->maxx / 4;
211 hp->js = hp->maxy / 4;
221 hp->is = hp->maxx / 4;
222 hp->js = hp->maxx / 4;
224 hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5 - 0.5;
225 hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5;
228 for (i = 0; i < MAXITER && x * x + y * y < 13; i++) { /* 'Brot calc */
229 xn = x * x - y * y + hp->a;
230 yn = 2 * x * y + hp->b;
234 } while (i < MAXITER); /* wait for a connected set */
242 if (hp->pointBuffer == NULL)
243 hp->pointBuffer = (XPoint *) malloc(MI_COUNT(mi) * sizeof (XPoint));
245 /* Clear the background. */
253 draw_discrete(ModeInfo * mi)
255 Display *dsp = MI_DISPLAY(mi);
256 Window win = MI_WINDOW(mi);
258 int batchcount = MI_COUNT(mi);
259 int cycles = MI_CYCLES(mi);
263 discretestruct *hp = &discretes[MI_SCREEN(mi)];
266 xp = hp->pointBuffer;
270 if (MI_NPIXELS(mi) > 2) {
271 XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
272 if (++hp->pix >= MI_NPIXELS(mi))
285 XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi));
286 XFillRectangle(dsp, win, gc, 0, 0, hp->maxx, hp->maxy);
287 XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
292 if (k < batchcount / 4) {
293 hp->i = ((double) k / batchcount) * 8 - 1;
295 } else if (k < batchcount / 2) {
297 hp->j = 3 - ((double) k / batchcount) * 8;
298 } else if (k < 3 * batchcount / 4) {
299 hp->i = 5 - ((double) k / batchcount) * 8;
303 hp->j = ((double) k / batchcount) * 8 - 7;
305 for (i = 1; i < (hp->inc % 15); i++) {
309 hp->i = (hp->a * oldi + hp->b) * oldj;
310 hp->j = (hp->e - hp->d + hp->c * oldi) * oldj * oldj - hp->c * oldi + hp->d;
318 hp->i = hp->a * oldi * (1 - oldj);
321 hp->i = oldj + hp->a - hp->b * oldi * oldi;
322 hp->j = hp->c * oldi;
326 hp->j = hp->a + hp->i;
327 hp->i = -oldj + (hp->i < 0
328 ? sqrt(fabs(hp->b * (hp->i - hp->c)))
329 : -sqrt(fabs(hp->b * (hp->i - hp->c))));
333 hp->i = s * hp->inc * hp->maxx / cycles / 2;
334 hp->j = hp->a + hp->i;
340 hp->j = (1 - hp->a) * oldj + hp->b * sin(oldi) + hp->a * hp->c;
341 hp->j = fmod(hp->j + 2 * M_PI, 2 * M_PI);
342 hp->i = oldi + hp->j;
343 hp->i = fmod(hp->i + 2 * M_PI, 2 * M_PI);
347 hp->j = M_PI + fmod(s * hp->inc * 2 * M_PI / (cycles - 0.5), M_PI);
354 hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b;
359 double r2 = oldi * oldi + oldj * oldj;
361 hp->i = hp->a + hp->b * (oldi * cos(r2) - oldj * sin(r2));
362 hp->j = hp->b * (oldj * cos(r2) + oldi * sin(r2));
367 hp->j = hp->a * oldj - oldj * oldj * oldj - hp->b * oldi;
370 hp->i = ((LRAND() < MAXRAND / 2) ? -1 : 1) *
371 sqrt(((oldi - hp->a) +
372 sqrt((oldi - hp->a) * (oldi - hp->a) + (oldj - hp->b) * (oldj - hp->b))) / 2);
373 hp->j = (oldj - hp->b) / (2 * hp->i);
376 xp->x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is);
377 xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js);
380 XDrawPoints(dsp, win, gc, hp->pointBuffer, batchcount, CoordModeOrigin);
381 if (++hp->count > cycles) {
383 erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
384 #endif /* STANDALONE */
390 release_discrete(ModeInfo * mi)
392 if (discretes != NULL) {
395 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
396 discretestruct *hp = &discretes[screen];
398 if (hp->pointBuffer != NULL)
399 (void) free((void *) hp->pointBuffer);
401 (void) free((void *) discretes);
407 refresh_discrete(ModeInfo * mi)