1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* discrete --- chaotic mappings */
5 static const char sccsid[] = "@(#)discrete.c 5.00 2000/11/01 xlockmore";
9 * Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com>
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation.
17 * This file is provided AS IS with no warranties of any kind. The author
18 * shall have no liability with respect to the infringement of copyrights,
19 * trade secrets or any patents by this file or any part thereof. In no
20 * event will the author be liable for any lost revenue or profits or
21 * other special, indirect and consequential damages.
23 * "discrete" shows a number of fractals based on the "discrete map"
24 * type of dynamical systems. They include a different way of looking
25 * at the HOPALONG system, an inverse julia-set iteration, the "Standard
26 * Map" and the "Bird in a Thornbush" fractal.
29 * 01-Nov-2000: Allocation checks
30 * 31-Jul-1997: Ported to xlockmore-4
31 * 08-Aug-1996: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton.
35 # define MODE_discrete
36 #define DEFAULTS "*delay: 20000 \n" \
40 "*fpsSolid: true \n" \
41 "*ignoreRotation: True \n" \
44 # define SMOOTH_COLORS
45 # define release_discrete 0
46 # define discrete_handle_event 0
47 # include "xlockmore.h" /* in xscreensaver distribution */
48 #else /* STANDALONE */
49 # include "xlock.h" /* in xlockmore distribution */
50 #endif /* STANDALONE */
54 ENTRYPOINT ModeSpecOpt discrete_opts =
55 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
58 ModStruct discrete_description =
59 {"discrete", "init_discrete", "draw_discrete", (char *) NULL,
60 "refresh_discrete", "init_discrete", "free_discrete", &discrete_opts,
61 1000, 4096, 2500, 1, 64, 1.0, "",
62 "Shows various discrete maps", 0, NULL};
67 SQRT, BIRDIE, STANDARD, TRIG, CUBIC, HENON, AILUJ, HSHOE, DELOG
70 /*#define TEST STANDARD */
73 static enum ftypes bias[BIASES] =
75 STANDARD, STANDARD, STANDARD, STANDARD,
76 SQRT, SQRT, SQRT, SQRT,
77 BIRDIE, BIRDIE, BIRDIE,
86 int maxy; /* max of the screen */
93 double j; /* discrete parameters */
102 XPoint *pointBuffer; /* pointer for XDrawPoints */
104 int sqrt_sign, std_sign;
108 static discretestruct *discretes = (discretestruct *) NULL;
111 init_discrete (ModeInfo * mi)
116 MI_INIT (mi, discretes);
117 hp = &discretes[MI_SCREEN(mi)];
119 hp->maxx = MI_WIDTH(mi);
120 hp->maxy = MI_HEIGHT(mi);
124 hp->op = bias[LRAND() % BIASES];
130 hp->is = hp->maxx / (4);
131 hp->js = hp->maxy / (4);
142 hp->is = hp->maxx / 1.5;
143 hp->js = hp->maxy / 1.5;
145 hp->i = hp->j = 0.01;
148 hp->jc = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.4;
149 hp->ic = 1.3 * (1 - (hp->jc * hp->jc) / (0.4 * 0.4));
151 hp->js = hp->maxy * 1.5;
162 range = sqrt((double) hp->maxx * 2 * hp->maxx * 2 +
163 (double) hp->maxy * 2 * hp->maxy * 2) /
164 (10.0 + LRAND() % 10);
166 hp->a = (LRAND() / MAXRAND) * range - range / 2.0;
167 hp->b = (LRAND() / MAXRAND) * range - range / 2.0;
168 hp->c = (LRAND() / MAXRAND) * range - range / 2.0;
176 hp->is = hp->maxx / (M_PI * 2);
177 hp->js = hp->maxy / (M_PI * 2);
178 hp->a = 0; /* decay */
179 hp->b = (LRAND() / MAXRAND) * 2.0;
187 hp->is = hp->maxx / 2;
188 hp->js = hp->maxy / 2;
189 hp->a = 1.99 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.2;
191 hp->c = 0.8 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
196 hp->b = 0.5 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.3;
199 hp->is = hp->maxx / (hp->b * 20);
200 hp->js = hp->maxy / (hp->b * 20);
205 hp->b = 0.1 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
208 hp->is = hp->maxx / 4;
209 hp->js = hp->maxy / 4;
219 hp->is = hp->maxx / 4;
220 hp->js = hp->maxx / 4;
222 hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5 - 0.5;
223 hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5;
226 for (i = 0; i < MAXITER && x * x + y * y < 13; i++) { /* 'Brot calc */
227 xn = x * x - y * y + hp->a;
228 yn = 2 * x * y + hp->b;
232 } while (i < MAXITER); /* wait for a connected set */
240 if (hp->pointBuffer == NULL) {
241 hp->pointBuffer = (XPoint *) malloc(sizeof (XPoint) * MI_COUNT(mi));
242 /* if fails will check later */
245 /* Clear the background. */
248 XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi));
256 draw_discrete_1 (ModeInfo * mi)
258 Display *dsp = MI_DISPLAY(mi);
259 Window win = MI_WINDOW(mi);
261 int count = MI_COUNT(mi);
262 int cycles = MI_CYCLES(mi);
268 if (discretes == NULL)
270 hp = &discretes[MI_SCREEN(mi)];
271 if (hp->pointBuffer == NULL)
275 xp = hp->pointBuffer;
279 MI_IS_DRAWN(mi) = True;
281 if (MI_NPIXELS(mi) > 2) {
282 XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
283 if (++hp->pix >= MI_NPIXELS(mi))
296 XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi));
297 XFillRectangle(dsp, win, gc, 0, 0, hp->maxx, hp->maxy);
298 XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
304 hp->i = ((double) k / count) * 8 - 1;
306 } else if (k < count / 2) {
308 hp->j = 3 - ((double) k / count) * 8;
309 } else if (k < 3 * count / 4) {
310 hp->i = 5 - ((double) k / count) * 8;
314 hp->j = ((double) k / count) * 8 - 7;
316 for (i = 1; i < (hp->inc % 15); i++) {
320 hp->i = (hp->a * oldi + hp->b) * oldj;
321 hp->j = (hp->e - hp->d + hp->c * oldi) * oldj * oldj - hp->c * oldi + hp->d;
329 hp->i = hp->a * oldi * (1 - oldj);
332 hp->i = oldj + hp->a - hp->b * oldi * oldi;
333 hp->j = hp->c * oldi;
337 hp->j = hp->a + hp->i;
338 hp->i = -oldj + (hp->i < 0
339 ? sqrt(fabs(hp->b * (hp->i - hp->c)))
340 : -sqrt(fabs(hp->b * (hp->i - hp->c))));
342 hp->i = (hp->sqrt_sign ? 1 : -1) * hp->inc * hp->maxx / cycles / 2;
343 hp->j = hp->a + hp->i;
344 hp->sqrt_sign = !hp->sqrt_sign;
349 hp->j = (1 - hp->a) * oldj + hp->b * sin(oldi) + hp->a * hp->c;
350 hp->j = fmod(hp->j + 2 * M_PI, 2 * M_PI);
351 hp->i = oldi + hp->j;
352 hp->i = fmod(hp->i + 2 * M_PI, 2 * M_PI);
354 hp->j = M_PI + fmod((hp->std_sign ? 1 : -1) * hp->inc * 2 * M_PI / (cycles - 0.5), M_PI);
356 hp->std_sign = !hp->std_sign;
361 hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b;
366 double r2 = oldi * oldi + oldj * oldj;
368 hp->i = hp->a + hp->b * (oldi * cos(r2) - oldj * sin(r2));
369 hp->j = hp->b * (oldj * cos(r2) + oldi * sin(r2));
374 hp->j = hp->a * oldj - oldj * oldj * oldj - hp->b * oldi;
377 hp->i = ((LRAND() < MAXRAND / 2) ? -1 : 1) *
378 sqrt(((oldi - hp->a) +
379 sqrt((oldi - hp->a) * (oldi - hp->a) + (oldj - hp->b) * (oldj - hp->b))) / 2);
380 if (hp->i < 0.00000001 && hp->i > -0.00000001)
381 hp->i = (hp->i > 0.0) ? 0.00000001 : -0.00000001;
382 hp->j = (oldj - hp->b) / (2 * hp->i);
385 xp->x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is);
386 xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js);
389 XDrawPoints(dsp, win, gc, hp->pointBuffer, count, CoordModeOrigin);
393 draw_discrete (ModeInfo * mi)
395 discretestruct *hp = &discretes[MI_SCREEN(mi)];
396 int cycles = MI_CYCLES(mi);
399 for (i = 0; i < 10; i++) {
400 draw_discrete_1 (mi);
404 if (hp->count > cycles) {
411 reshape_discrete(ModeInfo * mi, int width, int height)
413 discretestruct *hp = &discretes[MI_SCREEN(mi)];
416 XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi));
420 free_discrete(ModeInfo * mi)
422 discretestruct *hp = &discretes[MI_SCREEN(mi)];
424 if (hp->pointBuffer != NULL) {
425 (void) free((void *) hp->pointBuffer);
426 /* hp->pointBuffer = NULL; */
432 refresh_discrete(ModeInfo * mi)
438 XSCREENSAVER_MODULE ("Discrete", discrete)
440 #endif /* MODE_discrete */