source: trunk/third/xscreensaver/hacks/discrete.c @ 20148

Revision 20148, 10.2 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 4 -*- */
2/* discrete --- chaotic mappings */
3
4#if 0
5static const char sccsid[] = "@(#)discrete.c    5.00 2000/11/01 xlockmore";
6#endif
7
8/*-
9 * Copyright (c) 1996 by Tim Auckland <Tim.Auckland@Procket.com>
10 *
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.
16 *
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.
22 *
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.
27 *
28 * Revision History:
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.
32 */
33
34#ifdef STANDALONE
35#define MODE_discrete
36#define PROGCLASS "Discrete"
37#define HACK_INIT init_discrete
38#define HACK_DRAW draw_discrete
39#define discrete_opts xlockmore_opts
40#define DEFAULTS "*delay: 1000 \n" \
41 "*count: 4096 \n" \
42 "*cycles: 2500 \n" \
43 "*ncolors: 100 \n"
44#define SMOOTH_COLORS
45#include "xlockmore.h"          /* in xscreensaver distribution */
46#include "erase.h"
47#else /* STANDALONE */
48#include "xlock.h"              /* in xlockmore distribution */
49#endif /* STANDALONE */
50
51#ifdef MODE_discrete
52
53ModeSpecOpt discrete_opts =
54{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
55
56#ifdef USE_MODULES
57ModStruct   discrete_description =
58{"discrete", "init_discrete", "draw_discrete", "release_discrete",
59 "refresh_discrete", "init_discrete", (char *) NULL, &discrete_opts,
60 1000, 4096, 2500, 1, 64, 1.0, "",
61 "Shows various discrete maps", 0, NULL};
62
63#endif
64
65enum ftypes {
66        SQRT, BIRDIE, STANDARD, TRIG, CUBIC, HENON, AILUJ, HSHOE, DELOG
67};
68
69/*#define TEST STANDARD */
70
71#define BIASES 18
72static enum ftypes bias[BIASES] =
73{
74        STANDARD, STANDARD, STANDARD, STANDARD,
75        SQRT, SQRT, SQRT, SQRT,
76        BIRDIE, BIRDIE, BIRDIE,
77        AILUJ, AILUJ, AILUJ,
78        TRIG, TRIG,
79        CUBIC,
80        HENON,
81};
82
83typedef struct {
84        int         maxx;
85        int         maxy;       /* max of the screen */
86        double      a;
87        double      b;
88        double      c;
89        double      d;
90        double      e;
91        double      i;
92        double      j;          /* discrete parameters */
93        double      ic;
94        double      jc;
95        double      is;
96        double      js;
97        int         inc;
98        int         pix;
99        enum ftypes op;
100        int         count;
101        XPoint     *pointBuffer;        /* pointer for XDrawPoints */
102} discretestruct;
103
104static discretestruct *discretes = (discretestruct *) NULL;
105
106void
107init_discrete(ModeInfo * mi)
108{
109        double      range;
110        discretestruct *hp;
111
112        if (discretes == NULL) {
113                if ((discretes =
114                     (discretestruct *) calloc(MI_NUM_SCREENS(mi),
115                                           sizeof (discretestruct))) == NULL)
116                        return;
117        }
118        hp = &discretes[MI_SCREEN(mi)];
119
120        hp->maxx = MI_WIDTH(mi);
121        hp->maxy = MI_HEIGHT(mi);
122#ifdef TEST
123        hp->op = TEST;
124#else
125        hp->op = bias[LRAND() % BIASES];
126#endif
127        switch (hp->op) {
128                case HSHOE:
129                        hp->ic = 0;
130                        hp->jc = 0;
131                        hp->is = hp->maxx / (4);
132                        hp->js = hp->maxy / (4);
133                        hp->a = 0.5;
134                        hp->b = 0.5;
135                        hp->c = 0.2;
136                        hp->d = -1.25;
137                        hp->e = 1;
138                        hp->i = hp->j = 0.0;
139                        break;
140                case DELOG:
141                        hp->ic = 0.5;
142                        hp->jc = 0.3;
143                        hp->is = hp->maxx / 1.5;
144                        hp->js = hp->maxy / 1.5;
145                        hp->a = 2.176399;
146                        hp->i = hp->j = 0.01;
147                        break;
148                case HENON:
149                        hp->jc = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.4;
150                        hp->ic = 1.3 * (1 - (hp->jc * hp->jc) / (0.4 * 0.4));
151                        hp->is = hp->maxx;
152                        hp->js = hp->maxy * 1.5;
153                        hp->a = 1;
154                        hp->b = 1.4;
155                        hp->c = 0.3;
156                        hp->i = hp->j = 0;
157                        break;
158                case SQRT:
159                        hp->ic = 0;
160                        hp->jc = 0;
161                        hp->is = 1;
162                        hp->js = 1;
163                        range = sqrt((double) hp->maxx * 2 * hp->maxx * 2 +
164                                     (double) hp->maxy * 2 * hp->maxy * 2) /
165                                (10.0 + LRAND() % 10);
166
167                        hp->a = (LRAND() / MAXRAND) * range - range / 2.0;
168                        hp->b = (LRAND() / MAXRAND) * range - range / 2.0;
169                        hp->c = (LRAND() / MAXRAND) * range - range / 2.0;
170                        if (!(LRAND() % 2))
171                                hp->c = 0.0;
172                        hp->i = hp->j = 0.0;
173                        break;
174                case STANDARD:
175                        hp->ic = M_PI;
176                        hp->jc = M_PI;
177                        hp->is = hp->maxx / (M_PI * 2);
178                        hp->js = hp->maxy / (M_PI * 2);
179                        hp->a = 0;      /* decay */
180                        hp->b = (LRAND() / MAXRAND) * 2.0;
181                        hp->c = 0;
182                        hp->i = M_PI;
183                        hp->j = M_PI;
184                        break;
185                case BIRDIE:
186                        hp->ic = 0;
187                        hp->jc = 0;
188                        hp->is = hp->maxx / 2;
189                        hp->js = hp->maxy / 2;
190                        hp->a = 1.99 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.2;
191                        hp->b = 0;
192                        hp->c = 0.8 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
193                        hp->i = hp->j = 0;
194                        break;
195                case TRIG:
196                        hp->a = 5;
197                        hp->b = 0.5 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.3;
198                        hp->ic = hp->a;
199                        hp->jc = 0;
200                        hp->is = hp->maxx / (hp->b * 20);
201                        hp->js = hp->maxy / (hp->b * 20);
202                        hp->i = hp->j = 0;
203                        break;
204                case CUBIC:
205                        hp->a = 2.77;
206                        hp->b = 0.1 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1;
207                        hp->ic = 0;
208                        hp->jc = 0;
209                        hp->is = hp->maxx / 4;
210                        hp->js = hp->maxy / 4;
211                        hp->i = hp->j = 0.1;
212                        break;
213                case AILUJ:
214                        {
215                                int         i;
216                                double      x, y, xn, yn;
217
218                                hp->ic = 0;
219                                hp->jc = 0;
220                                hp->is = hp->maxx / 4;
221                                hp->js = hp->maxx / 4;
222                                do {
223                                        hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5 - 0.5;
224                                        hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5;
225                                        x = y = 0;
226#define MAXITER 10
227                                        for (i = 0; i < MAXITER && x * x + y * y < 13; i++) {   /* 'Brot calc */
228                                                xn = x * x - y * y + hp->a;
229                                                yn = 2 * x * y + hp->b;
230                                                x = xn;
231                                                y = yn;
232                                        }
233                                } while (i < MAXITER);  /* wait for a connected set */
234                                hp->i = hp->j = 0.1;
235                                break;
236                        }
237        }
238        hp->pix = 0;
239        hp->inc = 0;
240
241        if (hp->pointBuffer == NULL) {
242                hp->pointBuffer = (XPoint *) malloc(sizeof (XPoint) * MI_COUNT(mi));
243                /* if fails will check later */
244        }
245
246        /* Clear the background. */
247        MI_CLEARWINDOW(mi);
248
249        XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi));
250        hp->count = 0;
251}
252
253
254void
255draw_discrete(ModeInfo * mi)
256{
257        Display    *dsp = MI_DISPLAY(mi);
258        Window      win = MI_WINDOW(mi);
259        double      oldj, oldi;
260        int         count = MI_COUNT(mi);
261        int         cycles = MI_CYCLES(mi);
262        int         k;
263        XPoint     *xp;
264        GC          gc = MI_GC(mi);
265        discretestruct *hp;
266
267        if (discretes == NULL)
268                return;
269        hp = &discretes[MI_SCREEN(mi)];
270        if (hp->pointBuffer == NULL)
271                return;
272
273        k = count;
274        xp = hp->pointBuffer;
275
276        hp->inc++;
277
278        MI_IS_DRAWN(mi) = True;
279
280        if (MI_NPIXELS(mi) > 2) {
281                XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
282                if (++hp->pix >= MI_NPIXELS(mi))
283                        hp->pix = 0;
284        }
285        while (k--) {
286                oldj = hp->j;
287                oldi = hp->i;
288                switch (hp->op) {
289                        case HSHOE:
290                                {
291                                        int         i;
292
293#if 0
294                                        if (!k) {
295                                                XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi));
296                                                XFillRectangle(dsp, win, gc, 0, 0, hp->maxx, hp->maxy);
297                                                XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix));
298                                        } else
299#endif
300#define HD
301#ifdef HD
302                                        if (k < count / 4) {
303                                                hp->i = ((double) k / count) * 8 - 1;
304                                                hp->j = 1;
305                                        } else if (k < count / 2) {
306                                                hp->i = 1;
307                                                hp->j = 3 - ((double) k / count) * 8;
308                                        } else if (k < 3 * count / 4) {
309                                                hp->i = 5 - ((double) k / count) * 8;
310                                                hp->j = -1;
311                                        } else {
312                                                hp->i = -1;
313                                                hp->j = ((double) k / count) * 8 - 7;
314                                        }
315                                        for (i = 1; i < (hp->inc % 15); i++) {
316                                                oldj = hp->j;
317                                                oldi = hp->i;
318#endif
319                                                hp->i = (hp->a * oldi + hp->b) * oldj;
320                                                hp->j = (hp->e - hp->d + hp->c * oldi) * oldj * oldj - hp->c * oldi + hp->d;
321#ifdef HD
322                                        }
323#endif
324                                        break;
325                                }
326                        case DELOG:
327                                hp->j = oldi;
328                                hp->i = hp->a * oldi * (1 - oldj);
329                                break;
330                        case HENON:
331                                hp->i = oldj + hp->a - hp->b * oldi * oldi;
332                                hp->j = hp->c * oldi;
333                                break;
334                        case SQRT:
335                                if (k) {
336                                        hp->j = hp->a + hp->i;
337                                        hp->i = -oldj + (hp->i < 0
338                                        ? sqrt(fabs(hp->b * (hp->i - hp->c)))
339                                                         : -sqrt(fabs(hp->b * (hp->i - hp->c))));
340                                } else {
341                                        static int  s = 1;
342
343                                        hp->i = s * hp->inc * hp->maxx / cycles / 2;
344                                        hp->j = hp->a + hp->i;
345                                        s = -s;
346                                }
347                                break;
348                        case STANDARD:
349                                if (k) {
350                                        hp->j = (1 - hp->a) * oldj + hp->b * sin(oldi) + hp->a * hp->c;
351                                        hp->j = fmod(hp->j + 2 * M_PI, 2 * M_PI);
352                                        hp->i = oldi + hp->j;
353                                        hp->i = fmod(hp->i + 2 * M_PI, 2 * M_PI);
354                                } else {
355                                        static int  s = 1;
356
357                                        hp->j = M_PI + fmod(s * hp->inc * 2 * M_PI / (cycles - 0.5), M_PI);
358                                        hp->i = M_PI;
359                                        s = -s;
360                                }
361                                break;
362                        case BIRDIE:
363                                hp->j = oldi;
364                                hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b;
365                                hp->b = oldj;
366                                break;
367                        case TRIG:
368                                {
369                                        double      r2 = oldi * oldi + oldj * oldj;
370
371                                        hp->i = hp->a + hp->b * (oldi * cos(r2) - oldj * sin(r2));
372                                        hp->j = hp->b * (oldj * cos(r2) + oldi * sin(r2));
373                                }
374                                break;
375                        case CUBIC:
376                                hp->i = oldj;
377                                hp->j = hp->a * oldj - oldj * oldj * oldj - hp->b * oldi;
378                                break;
379                        case AILUJ:
380                                hp->i = ((LRAND() < MAXRAND / 2) ? -1 : 1) *
381                                        sqrt(((oldi - hp->a) +
382                                              sqrt((oldi - hp->a) * (oldi - hp->a) + (oldj - hp->b) * (oldj - hp->b))) / 2);
383                                if (hp->i < 0.00000001 && hp->i > -0.00000001)
384                                        hp->i = (hp->i > 0.0) ? 0.00000001 : -0.00000001;
385                                hp->j = (oldj - hp->b) / (2 * hp->i);
386                                break;
387                }
388                xp->x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is);
389                xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js);
390                xp++;
391        }
392        XDrawPoints(dsp, win, gc, hp->pointBuffer, count, CoordModeOrigin);
393        if (++hp->count > cycles) {
394#ifdef STANDALONE
395                erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
396#endif /* STANDALONE */
397                init_discrete(mi);
398        }
399}
400
401void
402release_discrete(ModeInfo * mi)
403{
404        if (discretes != NULL) {
405                int         screen;
406
407                for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
408                        discretestruct *hp = &discretes[screen];
409
410                        if (hp->pointBuffer != NULL) {
411                                (void) free((void *) hp->pointBuffer);
412                                /* hp->pointBuffer = NULL; */
413                        }
414                }
415                (void) free((void *) discretes);
416                discretes = (discretestruct *) NULL;
417        }
418}
419
420void
421refresh_discrete(ModeInfo * mi)
422{
423        MI_CLEARWINDOW(mi);
424}
425
426#endif /* MODE_discrete */
Note: See TracBrowser for help on using the repository browser.