diff options
Diffstat (limited to 'hacks/discrete.c')
-rw-r--r-- | hacks/discrete.c | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/hacks/discrete.c b/hacks/discrete.c new file mode 100644 index 0000000..bfb4459 --- /dev/null +++ b/hacks/discrete.c @@ -0,0 +1,440 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* discrete --- chaotic mappings */ + +#if 0 +static const char sccsid[] = "@(#)discrete.c 5.00 2000/11/01 xlockmore"; +#endif + +/*- + * Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com> + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * "discrete" shows a number of fractals based on the "discrete map" + * type of dynamical systems. They include a different way of looking + * at the HOPALONG system, an inverse julia-set iteration, the "Standard + * Map" and the "Bird in a Thornbush" fractal. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 31-Jul-1997: Ported to xlockmore-4 + * 08-Aug-1996: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton. + */ + +#ifdef STANDALONE +# define MODE_discrete +#define DEFAULTS "*delay: 20000 \n" \ + "*count: 4096 \n" \ + "*cycles: 2500 \n" \ + "*ncolors: 100 \n" \ + "*fpsSolid: true \n" \ + "*ignoreRotation: True \n" \ + "*lowrez: True \n" \ + +# define SMOOTH_COLORS +# define release_discrete 0 +# define discrete_handle_event 0 +# include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +# include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_discrete + +ENTRYPOINT ModeSpecOpt discrete_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct discrete_description = +{"discrete", "init_discrete", "draw_discrete", (char *) NULL, + "refresh_discrete", "init_discrete", "free_discrete", &discrete_opts, + 1000, 4096, 2500, 1, 64, 1.0, "", + "Shows various discrete maps", 0, NULL}; + +#endif + +enum ftypes { + SQRT, BIRDIE, STANDARD, TRIG, CUBIC, HENON, AILUJ, HSHOE, DELOG +}; + +/*#define TEST STANDARD */ + +#define BIASES 18 +static enum ftypes bias[BIASES] = +{ + STANDARD, STANDARD, STANDARD, STANDARD, + SQRT, SQRT, SQRT, SQRT, + BIRDIE, BIRDIE, BIRDIE, + AILUJ, AILUJ, AILUJ, + TRIG, TRIG, + CUBIC, + HENON, +}; + +typedef struct { + int maxx; + int maxy; /* max of the screen */ + double a; + double b; + double c; + double d; + double e; + double i; + double j; /* discrete parameters */ + double ic; + double jc; + double is; + double js; + int inc; + int pix; + enum ftypes op; + int count; + XPoint *pointBuffer; /* pointer for XDrawPoints */ + + int sqrt_sign, std_sign; + +} discretestruct; + +static discretestruct *discretes = (discretestruct *) NULL; + +ENTRYPOINT void +init_discrete (ModeInfo * mi) +{ + double range; + discretestruct *hp; + + MI_INIT (mi, discretes); + hp = &discretes[MI_SCREEN(mi)]; + + hp->maxx = MI_WIDTH(mi); + hp->maxy = MI_HEIGHT(mi); +#ifdef TEST + hp->op = TEST; +#else + hp->op = bias[LRAND() % BIASES]; +#endif + switch (hp->op) { + case HSHOE: + hp->ic = 0; + hp->jc = 0; + hp->is = hp->maxx / (4); + hp->js = hp->maxy / (4); + hp->a = 0.5; + hp->b = 0.5; + hp->c = 0.2; + hp->d = -1.25; + hp->e = 1; + hp->i = hp->j = 0.0; + break; + case DELOG: + hp->ic = 0.5; + hp->jc = 0.3; + hp->is = hp->maxx / 1.5; + hp->js = hp->maxy / 1.5; + hp->a = 2.176399; + hp->i = hp->j = 0.01; + break; + case HENON: + hp->jc = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.4; + hp->ic = 1.3 * (1 - (hp->jc * hp->jc) / (0.4 * 0.4)); + hp->is = hp->maxx; + hp->js = hp->maxy * 1.5; + hp->a = 1; + hp->b = 1.4; + hp->c = 0.3; + hp->i = hp->j = 0; + break; + case SQRT: + hp->ic = 0; + hp->jc = 0; + hp->is = 1; + hp->js = 1; + range = sqrt((double) hp->maxx * 2 * hp->maxx * 2 + + (double) hp->maxy * 2 * hp->maxy * 2) / + (10.0 + LRAND() % 10); + + hp->a = (LRAND() / MAXRAND) * range - range / 2.0; + hp->b = (LRAND() / MAXRAND) * range - range / 2.0; + hp->c = (LRAND() / MAXRAND) * range - range / 2.0; + if (!(LRAND() % 2)) + hp->c = 0.0; + hp->i = hp->j = 0.0; + break; + case STANDARD: + hp->ic = M_PI; + hp->jc = M_PI; + hp->is = hp->maxx / (M_PI * 2); + hp->js = hp->maxy / (M_PI * 2); + hp->a = 0; /* decay */ + hp->b = (LRAND() / MAXRAND) * 2.0; + hp->c = 0; + hp->i = M_PI; + hp->j = M_PI; + break; + case BIRDIE: + hp->ic = 0; + hp->jc = 0; + hp->is = hp->maxx / 2; + hp->js = hp->maxy / 2; + hp->a = 1.99 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.2; + hp->b = 0; + hp->c = 0.8 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1; + hp->i = hp->j = 0; + break; + case TRIG: + hp->a = 5; + hp->b = 0.5 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.3; + hp->ic = hp->a; + hp->jc = 0; + hp->is = hp->maxx / (hp->b * 20); + hp->js = hp->maxy / (hp->b * 20); + hp->i = hp->j = 0; + break; + case CUBIC: + hp->a = 2.77; + hp->b = 0.1 + ((LRAND() / MAXRAND) * 2.0 - 1.0) * 0.1; + hp->ic = 0; + hp->jc = 0; + hp->is = hp->maxx / 4; + hp->js = hp->maxy / 4; + hp->i = hp->j = 0.1; + break; + case AILUJ: + { + int i; + double x, y, xn, yn; + + hp->ic = 0; + hp->jc = 0; + hp->is = hp->maxx / 4; + hp->js = hp->maxx / 4; + do { + hp->a = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5 - 0.5; + hp->b = ((LRAND() / MAXRAND) * 2.0 - 1.0) * 1.5; + x = y = 0; +#define MAXITER 10 + for (i = 0; i < MAXITER && x * x + y * y < 13; i++) { /* 'Brot calc */ + xn = x * x - y * y + hp->a; + yn = 2 * x * y + hp->b; + x = xn; + y = yn; + } + } while (i < MAXITER); /* wait for a connected set */ + hp->i = hp->j = 0.1; + break; + } + } + hp->pix = 0; + hp->inc = 0; + + if (hp->pointBuffer == NULL) { + hp->pointBuffer = (XPoint *) malloc(sizeof (XPoint) * MI_COUNT(mi)); + /* if fails will check later */ + } + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); + hp->count = 0; + hp->sqrt_sign = 1; + hp->std_sign = 1; +} + + +static void +draw_discrete_1 (ModeInfo * mi) +{ + Display *dsp = MI_DISPLAY(mi); + Window win = MI_WINDOW(mi); + double oldj, oldi; + int count = MI_COUNT(mi); + int cycles = MI_CYCLES(mi); + int k; + XPoint *xp; + GC gc = MI_GC(mi); + discretestruct *hp; + + if (discretes == NULL) + return; + hp = &discretes[MI_SCREEN(mi)]; + if (hp->pointBuffer == NULL) + return; + + k = count; + xp = hp->pointBuffer; + + hp->inc++; + + MI_IS_DRAWN(mi) = True; + + if (MI_NPIXELS(mi) > 2) { + XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); + if (++hp->pix >= MI_NPIXELS(mi)) + hp->pix = 0; + } + while (k--) { + oldj = hp->j; + oldi = hp->i; + switch (hp->op) { + case HSHOE: + { + int i; + +#if 0 + if (!k) { + XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi)); + XFillRectangle(dsp, win, gc, 0, 0, hp->maxx, hp->maxy); + XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); + } else +#endif +#define HD +#ifdef HD + if (k < count / 4) { + hp->i = ((double) k / count) * 8 - 1; + hp->j = 1; + } else if (k < count / 2) { + hp->i = 1; + hp->j = 3 - ((double) k / count) * 8; + } else if (k < 3 * count / 4) { + hp->i = 5 - ((double) k / count) * 8; + hp->j = -1; + } else { + hp->i = -1; + hp->j = ((double) k / count) * 8 - 7; + } + for (i = 1; i < (hp->inc % 15); i++) { + oldj = hp->j; + oldi = hp->i; +#endif + hp->i = (hp->a * oldi + hp->b) * oldj; + hp->j = (hp->e - hp->d + hp->c * oldi) * oldj * oldj - hp->c * oldi + hp->d; +#ifdef HD + } +#endif + break; + } + case DELOG: + hp->j = oldi; + hp->i = hp->a * oldi * (1 - oldj); + break; + case HENON: + hp->i = oldj + hp->a - hp->b * oldi * oldi; + hp->j = hp->c * oldi; + break; + case SQRT: + if (k) { + hp->j = hp->a + hp->i; + hp->i = -oldj + (hp->i < 0 + ? sqrt(fabs(hp->b * (hp->i - hp->c))) + : -sqrt(fabs(hp->b * (hp->i - hp->c)))); + } else { + hp->i = (hp->sqrt_sign ? 1 : -1) * hp->inc * hp->maxx / cycles / 2; + hp->j = hp->a + hp->i; + hp->sqrt_sign = !hp->sqrt_sign; + } + break; + case STANDARD: + if (k) { + hp->j = (1 - hp->a) * oldj + hp->b * sin(oldi) + hp->a * hp->c; + hp->j = fmod(hp->j + 2 * M_PI, 2 * M_PI); + hp->i = oldi + hp->j; + hp->i = fmod(hp->i + 2 * M_PI, 2 * M_PI); + } else { + hp->j = M_PI + fmod((hp->std_sign ? 1 : -1) * hp->inc * 2 * M_PI / (cycles - 0.5), M_PI); + hp->i = M_PI; + hp->std_sign = !hp->std_sign; + } + break; + case BIRDIE: + hp->j = oldi; + hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b; + hp->b = oldj; + break; + case TRIG: + { + double r2 = oldi * oldi + oldj * oldj; + + hp->i = hp->a + hp->b * (oldi * cos(r2) - oldj * sin(r2)); + hp->j = hp->b * (oldj * cos(r2) + oldi * sin(r2)); + } + break; + case CUBIC: + hp->i = oldj; + hp->j = hp->a * oldj - oldj * oldj * oldj - hp->b * oldi; + break; + case AILUJ: + hp->i = ((LRAND() < MAXRAND / 2) ? -1 : 1) * + sqrt(((oldi - hp->a) + + sqrt((oldi - hp->a) * (oldi - hp->a) + (oldj - hp->b) * (oldj - hp->b))) / 2); + if (hp->i < 0.00000001 && hp->i > -0.00000001) + hp->i = (hp->i > 0.0) ? 0.00000001 : -0.00000001; + hp->j = (oldj - hp->b) / (2 * hp->i); + break; + } + xp->x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is); + xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); + xp++; + } + XDrawPoints(dsp, win, gc, hp->pointBuffer, count, CoordModeOrigin); +} + +ENTRYPOINT void +draw_discrete (ModeInfo * mi) +{ + discretestruct *hp = &discretes[MI_SCREEN(mi)]; + int cycles = MI_CYCLES(mi); + int i; + + for (i = 0; i < 10; i++) { + draw_discrete_1 (mi); + hp->count++; + } + + if (hp->count > cycles) { + init_discrete(mi); + } +} + + +ENTRYPOINT void +reshape_discrete(ModeInfo * mi, int width, int height) +{ + discretestruct *hp = &discretes[MI_SCREEN(mi)]; + hp->maxx = width; + hp->maxy = height; + XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi)); +} + +ENTRYPOINT void +free_discrete(ModeInfo * mi) +{ + discretestruct *hp = &discretes[MI_SCREEN(mi)]; + + if (hp->pointBuffer != NULL) { + (void) free((void *) hp->pointBuffer); + /* hp->pointBuffer = NULL; */ + } +} + +#ifndef STANDALONE +ENTRYPOINT void +refresh_discrete(ModeInfo * mi) +{ + MI_CLEARWINDOW(mi); +} +#endif + +XSCREENSAVER_MODULE ("Discrete", discrete) + +#endif /* MODE_discrete */ |