summaryrefslogtreecommitdiffstats
path: root/hacks/xlyap.c
diff options
context:
space:
mode:
authorSimon Rettberg2024-09-06 14:42:37 +0200
committerSimon Rettberg2024-09-06 14:42:37 +0200
commitbadef32037f52f79abc1f1440b786cd71afdf270 (patch)
tree412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/xlyap.c
parentDelete pre-6.00 files (diff)
downloadxscreensaver-master.tar.gz
xscreensaver-master.tar.xz
xscreensaver-master.zip
Diffstat (limited to 'hacks/xlyap.c')
-rw-r--r--hacks/xlyap.c1938
1 files changed, 0 insertions, 1938 deletions
diff --git a/hacks/xlyap.c b/hacks/xlyap.c
deleted file mode 100644
index f9204de..0000000
--- a/hacks/xlyap.c
+++ /dev/null
@@ -1,1938 +0,0 @@
-/* Lyap - calculate and display Lyapunov exponents */
-
-/* Written by Ron Record (rr@sco) 03 Sep 1991 */
-
-/* The idea here is to calculate the Lyapunov exponent for a periodically
- * forced logistic map (later i added several other nonlinear maps of the unit
- * interval). In order to turn the 1-dimensional parameter space of the
- * logistic map into a 2-dimensional parameter space, select two parameter
- * values ('a' and 'b') then alternate the iterations of the logistic map using
- * first 'a' then 'b' as the parameter. This program accepts an argument to
- * specify a forcing function, so instead of just alternating 'a' and 'b', you
- * can use 'a' as the parameter for say 6 iterations, then 'b' for 6 iterations
- * and so on. An interesting forcing function to look at is abbabaab (the
- * Morse-Thue sequence, an aperiodic self-similar, self-generating sequence).
- * Anyway, step through all the values of 'a' and 'b' in the ranges you want,
- * calculating the Lyapunov exponent for each pair of values. The exponent
- * is calculated by iterating out a ways (specified by the variable "settle")
- * then on subsequent iterations calculating an average of the logarithm of
- * the absolute value of the derivative at that point. Points in parameter
- * space with a negative Lyapunov exponent are colored one way (using the
- * value of the exponent to index into a color map) while points with a
- * non-negative exponent are colored differently.
- *
- * The algorithm was taken from the September 1991 Scientific American article
- * by A. K. Dewdney who gives credit to Mario Markus of the Max Planck
- * Institute for its creation. Additional information and ideas were gleaned
- * from the discussion on alt.fractals involving Stephen Hall, Ed Kubaitis,
- * Dave Platt and Baback Moghaddam. Assistance with colormaps and spinning
- * color wheels and X was gleaned from Hiram Clawson. Rubber banding code was
- * adapted from an existing Mandelbrot program written by Stacey Campbell.
- */
-
-#define LYAP_PATCHLEVEL 4
-#define LYAP_VERSION "#(@) lyap 2.3 2/20/92"
-
-#include <assert.h>
-#include <math.h>
-
-#include "screenhack.h"
-#include "yarandom.h"
-#include "hsv.h"
-
-#ifndef HAVE_JWXYZ
-# include <X11/cursorfont.h>
-#endif
-
-static const char *xlyap_defaults [] = {
- ".background: black",
- ".foreground: white",
- ".lowrez: true",
- "*fpsSolid: true",
- "*randomize: true",
- "*builtin: -1",
- "*minColor: 1",
- "*maxColor: 256",
- "*dwell: 50",
- "*useLog: false",
- "*colorExponent: 1.0",
- "*colorOffset: 0",
- "*randomForce: ", /* 0.5 */
- "*settle: 50",
- "*minA: 2.0",
- "*minB: 2.0",
- "*wheels: 7",
- "*function: 10101010",
- "*forcingFunction: abbabaab",
- "*bRange: ", /* 2.0 */
- "*startX: 0.65",
- "*mapIndex: ", /* 0 */
- "*outputFile: ",
- "*beNegative: false",
- "*rgbMax: 65000",
- "*spinLength: 256",
- "*show: false",
- "*aRange: ", /* 2.0 */
- "*delay: 10000",
- "*linger: 5",
- "*colors: 200",
-#ifdef HAVE_MOBILE
- "*ignoreRotation: True",
-#endif
- 0
-};
-
-static XrmOptionDescRec xlyap_options [] = {
- { "-randomize", ".randomize", XrmoptionNoArg, "true" },
- { "-builtin", ".builtin", XrmoptionSepArg, 0 },
- { "-C", ".minColor", XrmoptionSepArg, 0 }, /* n */
- { "-D", ".dwell", XrmoptionSepArg, 0 }, /* n */
- { "-L", ".useLog", XrmoptionNoArg, "true" },
- { "-M", ".colorExponent", XrmoptionSepArg, 0 }, /* r */
- { "-O", ".colorOffset", XrmoptionSepArg, 0 }, /* n */
- { "-R", ".randomForce", XrmoptionSepArg, 0 }, /* p */
- { "-S", ".settle", XrmoptionSepArg, 0 }, /* n */
- { "-a", ".minA", XrmoptionSepArg, 0 }, /* r */
- { "-b", ".minB", XrmoptionSepArg, 0 }, /* n */
- { "-c", ".wheels", XrmoptionSepArg, 0 }, /* n */
- { "-F", ".function", XrmoptionSepArg, 0 }, /* 10101010 */
- { "-f", ".forcingFunction", XrmoptionSepArg, 0 }, /* abbabaab */
- { "-h", ".bRange", XrmoptionSepArg, 0 }, /* r */
- { "-i", ".startX", XrmoptionSepArg, 0 }, /* r */
- { "-m", ".mapIndex", XrmoptionSepArg, 0 }, /* n */
- { "-o", ".outputFile", XrmoptionSepArg, 0 }, /* filename */
- { "-p", ".beNegative", XrmoptionNoArg, "true" },
- { "-r", ".rgbMax", XrmoptionSepArg, 0 }, /* n */
- { "-s", ".spinLength", XrmoptionSepArg, 0 }, /* n */
- { "-v", ".show", XrmoptionNoArg, "true" },
- { "-w", ".aRange", XrmoptionSepArg, 0 }, /* r */
- { "-delay", ".delay", XrmoptionSepArg, 0 }, /* delay */
- { "-linger", ".linger", XrmoptionSepArg, 0 }, /* linger */
- { 0, 0, 0, 0 }
-};
-
-
-#define ABS(a) (((a)<0) ? (0-(a)) : (a) )
-#define Min(x,y) ((x < y)?x:y)
-#define Max(x,y) ((x > y)?x:y)
-
-#ifdef SIXTEEN_COLORS
-# define MAXPOINTS 128
-# ifdef BIGMEM
-# define MAXFRAMES 4
-# else /* !BIGMEM */
-# define MAXFRAMES 2
-# endif /* !BIGMEM */
-# define MAXCOLOR 16
-#else /* !SIXTEEN_COLORS */
-# define MAXPOINTS 256
-# ifdef BIGMEM
-# define MAXFRAMES 8
-# else /* !BIGMEM */
-# define MAXFRAMES 2
-# endif /* !BIGMEM */
-# define MAXCOLOR 256
-#endif /* !SIXTEEN_COLORS */
-
-
-#define MAXINDEX 64
-#define FUNCMAXINDEX 16
-#define MAXWHEELS 7
-#define NUMMAPS 5
-#define NBUILTINS 22
-
-#ifndef TRUE
-# define TRUE 1
-# define FALSE 0
-#endif
-
-
-typedef struct {
- int x, y;
-} xy_t;
-
-#if 0
-typedef struct {
- int start_x, start_y;
- int last_x, last_y;
-} rubber_band_data_t;
-#endif
-
-typedef struct {
-# ifndef HAVE_JWXYZ
- Cursor band_cursor;
-# endif
- double p_min, p_max, q_min, q_max;
-/* rubber_band_data_t rubber_band;*/
-} image_data_t;
-
-typedef struct points_t {
- XPoint data[MAXCOLOR][MAXPOINTS];
- int npoints[MAXCOLOR];
-} points_t;
-
-
-typedef double (*PFD)(double,double);
-
-/* #### What was this for? Everything was drawn twice, to the window and
- to this, and this was never displayed! */
-/*#define BACKING_PIXMAP*/
-
-struct state {
- Display *dpy;
- Screen *screen;
- Visual *visual;
- Colormap cmap;
-
- unsigned long foreground, background;
-
- Window canvas;
- int delay, linger;
-
- unsigned int maxcolor, startcolor, mincolindex;
- int color_offset;
- int dwell, settle;
- int width, height, xposition, yposition;
-
- points_t Points;
-/* image_data_t rubber_data;*/
-
- GC Data_GC[MAXCOLOR]/*, RubberGC*/;
- PFD map, deriv;
-
- int aflag, bflag, wflag, hflag, Rflag;
-
- int maxindex;
- int funcmaxindex;
- double min_a, min_b, a_range, b_range, minlyap;
- double max_a, max_b;
- double start_x, lyapunov, a_inc, b_inc, a, b;
- int numcolors, numfreecols, lowrange;
- xy_t point;
-#ifdef BACKING_PIXMAP
- Pixmap pixmap;
-#endif
-/* XColor Colors[MAXCOLOR];*/
- double *exponents[MAXFRAMES];
- double a_minimums[MAXFRAMES], b_minimums[MAXFRAMES];
- double a_maximums[MAXFRAMES], b_maximums[MAXFRAMES];
- double minexp, maxexp, prob;
- int expind[MAXFRAMES], resized[MAXFRAMES];
- int numwheels, force, Force, negative;
- int rgb_max, nostart, stripe_interval;
- int save, show, useprod, spinlength;
- int maxframe, frame, dorecalc, mapindex, run;
- char *outname;
-
- int sendpoint_index;
-
- int forcing[MAXINDEX];
- int Forcing[FUNCMAXINDEX];
-
- int reset_countdown;
-
- int ncolors;
- XColor colors[MAXCOLOR];
-};
-
-
-static const double pmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static const double pmaxs[NUMMAPS] = { 4.0, 1.0, 6.75, 6.75, 16.0 };
-static const double amins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static const double aranges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
-static const double bmins[NUMMAPS] = { 2.0, 0.0, 0.0, 0.0, 0.0 };
-static const double branges[NUMMAPS] = { 2.0, 1.0, 6.75, 6.75, 16.0 };
-
-/****************************************************************************/
-
-/* callback function declarations
- */
-
-static double logistic(double,double);
-static double circle(double,double);
-static double leftlog(double,double);
-static double rightlog(double,double);
-static double doublelog(double,double);
-static double dlogistic(double,double);
-static double dcircle(double,double);
-static double dleftlog(double,double);
-static double drightlog(double,double);
-static double ddoublelog(double,double);
-
-static const PFD Maps[NUMMAPS] = { logistic, circle, leftlog, rightlog,
- doublelog };
-static const PFD Derivs[NUMMAPS] = { dlogistic, dcircle, dleftlog,
- drightlog, ddoublelog };
-
-
-/****************************************************************************/
-
-/* other function declarations
- */
-
-static void resize(struct state *);
-/*static void Spin(struct state *);*/
-static void show_defaults(struct state *);
-/*static void StartRubberBand(struct state *, image_data_t *, XEvent *);
-static void TrackRubberBand(struct state *, image_data_t *, XEvent *);
-static void EndRubberBand(struct state *, image_data_t *, XEvent *);*/
-/*static void CreateXorGC(struct state *);*/
-static void InitBuffer(struct state *);
-static void BufferPoint(struct state *, int color, int x, int y);
-static void FlushBuffer(struct state *);
-static void init_data(struct state *);
-static void init_color(struct state *);
-static void parseargs(struct state *);
-static void Clear(struct state *);
-static void setupmem(struct state *);
-static int complyap(struct state *);
-static Bool Getkey(struct state *, XKeyEvent *);
-static int sendpoint(struct state *, double expo);
-/*static void save_to_file(struct state *);*/
-static void setforcing(struct state *);
-static void check_params(struct state *, int mapnum, int parnum);
-static void usage(struct state *);
-static void Destroy_frame(struct state *);
-static void freemem(struct state *);
-static void Redraw(struct state *);
-static void redraw(struct state *, double *exparray, int index, int cont);
-static void recalc(struct state *);
-/*static void SetupCorners(XPoint *, image_data_t *);
-static void set_new_params(struct state *, image_data_t *);*/
-static void go_down(struct state *);
-static void go_back(struct state *);
-static void go_init(struct state *);
-static void jumpwin(struct state *);
-static void print_help(struct state *);
-static void print_values(struct state *);
-
-
-/****************************************************************************/
-
-
-/* complyap() is the guts of the program. This is where the Lyapunov exponent
- * is calculated. For each iteration (past some large number of iterations)
- * calculate the logarithm of the absolute value of the derivative at that
- * point. Then average them over some large number of iterations. Some small
- * speed up is achieved by utilizing the fact that log(a*b) = log(a) + log(b).
- */
-static int
-complyap(struct state *st)
-{
- int i, bindex;
- double total, prod, x, dx, r;
-
- if (st->maxcolor > MAXCOLOR)
- abort();
-
- if (!st->run)
- return TRUE;
- st->a += st->a_inc;
- if (st->a >= st->max_a) {
- if (sendpoint(st, st->lyapunov) == TRUE)
- return FALSE;
- else {
- FlushBuffer(st);
- /* if (savefile)
- save_to_file(); */
- return TRUE;
- }
- }
- if (st->b >= st->max_b) {
- FlushBuffer(st);
- /* if (savefile)
- save_to_file();*/
- return TRUE;
- }
- prod = 1.0;
- total = 0.0;
- bindex = 0;
- x = st->start_x;
- r = (st->forcing[bindex]) ? st->b : st->a;
-#ifdef MAPS
- findex = 0;
- map = Maps[st->Forcing[findex]];
-#endif
- for (i=0;i<st->settle;i++) { /* Here's where we let the thing */
- x = st->map (x, r); /* "settle down". There is usually */
- if (++bindex >= st->maxindex) { /* some initial "noise" in the */
- bindex = 0; /* iterations. How can we optimize */
- if (st->Rflag) /* the value of settle ??? */
- setforcing(st);
- }
- r = (st->forcing[bindex]) ? st->b : st->a;
-#ifdef MAPS
- if (++findex >= funcmaxindex)
- findex = 0;
- map = Maps[st->Forcing[findex]];
-#endif
- }
-#ifdef MAPS
- deriv = Derivs[st->Forcing[findex]];
-#endif
- if (st->useprod) { /* using log(a*b) */
- for (i=0;i<st->dwell;i++) {
- x = st->map (x, r);
- dx = st->deriv (x, r); /* ABS is a macro, so don't be fancy */
- dx = ABS(dx);
- if (dx == 0.0) /* log(0) is nasty so break out. */
- {
- i++;
- break;
- }
- prod *= dx;
- /* we need to prevent overflow and underflow */
- if ((prod > 1.0e12) || (prod < 1.0e-12)) {
- total += log(prod);
- prod = 1.0;
- }
- if (++bindex >= st->maxindex) {
- bindex = 0;
- if (st->Rflag)
- setforcing(st);
- }
- r = (st->forcing[bindex]) ? st->b : st->a;
-#ifdef MAPS
- if (++findex >= funcmaxindex)
- findex = 0;
- map = Maps[st->Forcing[findex]];
- deriv = Derivs[st->Forcing[findex]];
-#endif
- }
- total += log(prod);
- st->lyapunov = (total * M_LOG2E) / (double)i;
- }
- else { /* use log(a) + log(b) */
- for (i=0;i<st->dwell;i++) {
- x = st->map (x, r);
- dx = st->deriv (x, r); /* ABS is a macro, so don't be fancy */
- dx = ABS(dx);
- if (x == 0.0) /* log(0) check */
- {
- i++;
- break;
- }
- total += log(dx);
- if (++bindex >= st->maxindex) {
- bindex = 0;
- if (st->Rflag)
- setforcing(st);
- }
- r = (st->forcing[bindex]) ? st->b : st->a;
-#ifdef MAPS
- if (++findex >= funcmaxindex)
- findex = 0;
- map = Maps[st->Forcing[findex]];
- deriv = Derivs[st->Forcing[findex]];
-#endif
- }
- st->lyapunov = (total * M_LOG2E) / (double)i;
- }
-
- if (sendpoint(st, st->lyapunov) == TRUE)
- return FALSE;
- else {
- FlushBuffer(st);
- /* if (savefile)
- save_to_file();*/
- return TRUE;
- }
-}
-
-static double
-logistic(double x, double r) /* the familiar logistic map */
-{
- return(r * x * (1.0 - x));
-}
-
-static double
-dlogistic(double x, double r) /* the derivative of logistic map */
-{
- return(r - (2.0 * r * x));
-}
-
-static double
-circle(double x, double r) /* sin() hump or sorta like the circle map */
-{
- return(r * sin(M_PI * x));
-}
-
-static double
-dcircle(double x, double r) /* derivative of the "sin() hump" */
-{
- return(r * M_PI * cos(M_PI * x));
-}
-
-static double
-leftlog(double x, double r) /* left skewed logistic */
-{
- double d;
-
- d = 1.0 - x;
- return(r * x * d * d);
-}
-
-static double
-dleftlog(double x, double r) /* derivative of the left skewed logistic */
-{
- return(r * (1.0 - (4.0 * x) + (3.0 * x * x)));
-}
-
-static double
-rightlog(double x, double r) /* right skewed logistic */
-{
- return(r * x * x * (1.0 - x));
-}
-
-static double
-drightlog(double x, double r) /* derivative of the right skewed logistic */
-{
- return(r * ((2.0 * x) - (3.0 * x * x)));
-}
-
-static double
-doublelog(double x, double r) /* double logistic */
-{
- double d;
-
- d = 1.0 - x;
- return(r * x * x * d * d);
-}
-
-static double
-ddoublelog(double x, double r) /* derivative of the double logistic */
-{
- double d;
-
- d = x * x;
- return(r * ((2.0 * x) - (6.0 * d) + (4.0 * x * d)));
-}
-
-static void
-init_data(struct state *st)
-{
- st->numcolors = get_integer_resource (st->dpy, "colors", "Integer");
- if (st->numcolors < 2)
- st->numcolors = 2;
- if (st->numcolors > st->maxcolor)
- st->numcolors = st->maxcolor;
- st->numfreecols = st->numcolors - st->mincolindex;
- st->lowrange = st->mincolindex - st->startcolor;
- st->a_inc = st->a_range / (double)st->width;
- st->b_inc = st->b_range / (double)st->height;
- st->point.x = -1;
- st->point.y = 0;
- st->a = /*st->rubber_data.p_min = */st->min_a;
- st->b = /*st->rubber_data.q_min = */st->min_b;
-/* st->rubber_data.p_max = st->max_a;
- st->rubber_data.q_max = st->max_b;*/
- if (st->show)
- show_defaults(st);
- InitBuffer(st);
-}
-
-#if 0
-static void
-hls2rgb(int hue_light_sat[3],
- int rgb[3]) /* Each in range [0..65535] */
-{
- unsigned short r, g, b;
- hsv_to_rgb((int) (hue_light_sat[0] / 10), /* 0-3600 -> 0-360 */
- (int) ((hue_light_sat[2]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
- (int) ((hue_light_sat[1]/1000.0) * 64435), /* 0-1000 -> 0-65535 */
- &r, &g, &b);
- rgb[0] = r;
- rgb[1] = g;
- rgb[2] = b;
-}
-#endif /* 0 */
-
-
-static void
-init_color(struct state *st)
-{
- int i;
- if (st->ncolors)
- free_colors (st->screen, st->cmap, st->colors, st->ncolors);
- st->ncolors = st->maxcolor;
- make_smooth_colormap(st->screen, st->visual, st->cmap,
- st->colors, &st->ncolors, True, NULL, True);
-
- for (i = 0; i < st->maxcolor; i++) {
- if (! st->Data_GC[i]) {
- XGCValues gcv;
- gcv.background = BlackPixelOfScreen(st->screen);
- st->Data_GC[i] = XCreateGC(st->dpy, st->canvas, GCBackground, &gcv);
- }
- XSetForeground(st->dpy, st->Data_GC[i],
- st->colors[((int) ((i / ((float)st->maxcolor)) *
- st->ncolors))].pixel);
- }
-}
-
-
-static void
-parseargs(struct state *st)
-{
- int i;
- int bindex=0, findex;
- char *s, *ch;
-
- st->map = Maps[0];
- st->deriv = Derivs[0];
- st->maxexp=st->minlyap; st->minexp= -1.0 * st->minlyap;
-
- st->mincolindex = get_integer_resource(st->dpy, "minColor", "Integer");
- st->dwell = get_integer_resource(st->dpy, "dwell", "Integer");
-#ifdef MAPS
- {
- char *optarg = get_string_resource(st->dpy, "function", "String");
- funcmaxindex = strlen(optarg);
- if (funcmaxindex > FUNCMAXINDEX)
- usage();
- ch = optarg;
- st->Force++;
- for (findex=0;findex<funcmaxindex;findex++) {
- st->Forcing[findex] = (int)(*ch++ - '0');;
- if (st->Forcing[findex] >= NUMMAPS)
- usage();
- }
- if (optarg) free (optarg);
- }
-#endif
- if (get_boolean_resource(st->dpy, "useLog", "Boolean"))
- st->useprod=0;
-
- st->minlyap=ABS(get_float_resource(st->dpy, "colorExponent", "Float"));
- st->maxexp=st->minlyap;
- st->minexp= -1.0 * st->minlyap;
-
- st->color_offset = get_integer_resource(st->dpy, "colorOffset", "Integer");
-
- st->maxcolor=ABS(get_integer_resource(st->dpy, "maxColor", "Integer"));
- if ((st->maxcolor - st->startcolor) <= 0)
- st->startcolor = get_pixel_resource(st->dpy, st->cmap,
- "background", "Background");
- if ((st->maxcolor - st->mincolindex) <= 0) {
- st->mincolindex = 1;
- st->color_offset = 0;
- }
-
- s = get_string_resource(st->dpy, "randomForce", "Float");
- if (s && *s) {
- st->prob=atof(s); st->Rflag++; setforcing(st);
- }
- if (s) free (s);
-
- st->settle = get_integer_resource(st->dpy, "settle", "Integer");
-
-#if 0
- s = get_string_resource(st->dpy, "minA", "Float");
- if (s && *s) {
- st->min_a = atof(s);
- st->aflag++;
- }
- if (s) free (s);
-
- s = get_string_resource(st->dpy, "minB", "Float");
- if (s && *s) {
- st->min_b=atof(s); st->bflag++;
- }
- if (s) free (s);
-#else
- st->min_a = get_float_resource (st->dpy, "minA", "Float");
- st->aflag++;
- st->min_b = get_float_resource (st->dpy, "minB", "Float");
- st->bflag++;
-#endif
-
-
- st->numwheels = get_integer_resource(st->dpy, "wheels", "Integer");
-
- s = get_string_resource(st->dpy, "forcingFunction", "String");
- if (s && *s) {
- st->maxindex = strlen(s);
- if (st->maxindex > MAXINDEX)
- usage(st);
- ch = s;
- st->force++;
- while (bindex < st->maxindex) {
- if (*ch == 'a')
- st->forcing[bindex++] = 0;
- else if (*ch == 'b')
- st->forcing[bindex++] = 1;
- else
- usage(st);
- ch++;
- }
- }
- if (s) free (s);
-
- s = get_string_resource(st->dpy, "bRange", "Float");
- if (s && *s) {
- st->b_range = atof(s);
- st->hflag++;
- }
- if (s) free (s);
-
- st->start_x = get_float_resource(st->dpy, "startX", "Float");
-
- s = get_string_resource(st->dpy, "mapIndex", "Integer");
- if (s && *s) {
- st->mapindex=atoi(s);
- if ((st->mapindex >= NUMMAPS) || (st->mapindex < 0))
- usage(st);
- st->map = Maps[st->mapindex];
- st->deriv = Derivs[st->mapindex];
- if (!st->aflag)
- st->min_a = amins[st->mapindex];
- if (!st->wflag)
- st->a_range = aranges[st->mapindex];
- if (!st->bflag)
- st->min_b = bmins[st->mapindex];
- if (!st->hflag)
- st->b_range = branges[st->mapindex];
- if (!st->Force)
- for (i=0;i<FUNCMAXINDEX;i++)
- st->Forcing[i] = st->mapindex;
- }
- if (s) free (s);
-
- st->outname = get_string_resource(st->dpy, "outputFile", "Integer");
-
- if (get_boolean_resource(st->dpy, "beNegative", "Boolean"))
- st->negative--;
-
- st->rgb_max = get_integer_resource(st->dpy, "rgbMax", "Integer");
- st->spinlength = get_integer_resource(st->dpy, "spinLength", "Integer");
- st->show = get_boolean_resource(st->dpy, "show", "Boolean");
-
- s = get_string_resource(st->dpy, "aRange", "Float");
- if (s && *s) {
- st->a_range = atof(s); st->wflag++;
- }
- if (s) free (s);
-
- st->max_a = st->min_a + st->a_range;
- st->max_b = st->min_b + st->b_range;
-
- st->a_minimums[0] = st->min_a; st->b_minimums[0] = st->min_b;
- st->a_maximums[0] = st->max_a; st->b_maximums[0] = st->max_b;
-
- if (st->Force)
- if (st->maxindex == st->funcmaxindex)
- for (findex=0;findex<st->funcmaxindex;findex++)
- check_params(st, st->Forcing[findex],st->forcing[findex]);
- else
- fprintf(stderr, "Warning! Unable to check parameters\n");
- else
- check_params(st, st->mapindex,2);
-}
-
-static void
-check_params(struct state *st, int mapnum, int parnum)
-{
-
- if (parnum != 1) {
- if ((st->max_a > pmaxs[mapnum]) || (st->min_a < pmins[mapnum])) {
- fprintf(stderr, "Warning! Parameter 'a' out of range.\n");
- fprintf(stderr, "You have requested a range of (%f,%f).\n",
- st->min_a,st->max_a);
- fprintf(stderr, "Valid range is (%f,%f).\n",
- pmins[mapnum],pmaxs[mapnum]);
- }
- }
- if (parnum != 0) {
- if ((st->max_b > pmaxs[mapnum]) || (st->min_b < pmins[mapnum])) {
- fprintf(stderr, "Warning! Parameter 'b' out of range.\n");
- fprintf(stderr, "You have requested a range of (%f,%f).\n",
- st->min_b,st->max_b);
- fprintf(stderr, "Valid range is (%f,%f).\n",
- pmins[mapnum],pmaxs[mapnum]);
- }
- }
-}
-
-static void
-usage(struct state *st)
-{
- fprintf(stderr,"lyap [-BLs][-W#][-H#][-a#][-b#][-w#][-h#][-x xstart]\n");
- fprintf(stderr,"\t[-M#][-S#][-D#][-f string][-r#][-O#][-C#][-c#][-m#]\n");
-#ifdef MAPS
- fprintf(stderr,"\t[-F string]\n");
-#endif
- fprintf(stderr,"\tWhere: -C# specifies the minimum color index\n");
- fprintf(stderr,"\t -r# specifies the maxzimum rgb value\n");
- fprintf(stderr,"\t -u displays this message\n");
- fprintf(stderr,"\t -a# specifies the minimum horizontal parameter\n");
- fprintf(stderr,"\t -b# specifies the minimum vertical parameter\n");
- fprintf(stderr,"\t -w# specifies the horizontal parameter range\n");
- fprintf(stderr,"\t -h# specifies the vertical parameter range\n");
- fprintf(stderr,"\t -D# specifies the dwell\n");
- fprintf(stderr,"\t -S# specifies the settle\n");
- fprintf(stderr,"\t -H# specifies the initial window height\n");
- fprintf(stderr,"\t -W# specifies the initial window width\n");
- fprintf(stderr,"\t -O# specifies the color offset\n");
- fprintf(stderr,"\t -c# specifies the desired color wheel\n");
- fprintf(stderr,"\t -m# specifies the desired map (0-4)\n");
- fprintf(stderr,"\t -f aabbb specifies a forcing function of 00111\n");
-#ifdef MAPS
- fprintf(stderr,"\t -F 00111 specifies the function forcing function\n");
-#endif
- fprintf(stderr,"\t -L indicates use log(x)+log(y) rather than log(xy)\n");
- fprintf(stderr,"\tDuring display :\n");
- fprintf(stderr,"\t Use the mouse to zoom in on an area\n");
- fprintf(stderr,"\t e or E recalculates color indices\n");
- fprintf(stderr,"\t f or F saves exponents to a file\n");
- fprintf(stderr,"\t KJmn increase/decrease minimum negative exponent\n");
- fprintf(stderr,"\t r or R redraws\n");
- fprintf(stderr,"\t s or S spins the colorwheel\n");
- fprintf(stderr,"\t w or W changes the color wheel\n");
- fprintf(stderr,"\t x or X clears the window\n");
- fprintf(stderr,"\t q or Q exits\n");
- exit(1);
-}
-
-static void
-Cycle_frames(struct state *st)
-{
- int i;
- for (i=0;i<=st->maxframe;i++)
- redraw(st, st->exponents[i], st->expind[i], 1);
-}
-
-#if 0
-static void
-Spin(struct state *st)
-{
- int i, j;
- long tmpxcolor;
-
- if (!mono_p) {
- for (j=0;j<st->spinlength;j++) {
- tmpxcolor = st->Colors[st->mincolindex].pixel;
- for (i=st->mincolindex;i<st->numcolors-1;i++)
- st->Colors[i].pixel = st->Colors[i+1].pixel;
- st->Colors[st->numcolors-1].pixel = tmpxcolor;
- XStoreColors(st->dpy, st->cmap, st->Colors, st->numcolors);
- }
- for (j=0;j<st->spinlength;j++) {
- tmpxcolor = st->Colors[st->numcolors-1].pixel;
- for (i=st->numcolors-1;i>st->mincolindex;i--)
- st->Colors[i].pixel = st->Colors[i-1].pixel;
- st->Colors[st->mincolindex].pixel = tmpxcolor;
- XStoreColors(st->dpy, st->cmap, st->Colors, st->numcolors);
- }
- }
-}
-#endif
-
-static Bool
-Getkey(struct state *st, XKeyEvent *event)
-{
- unsigned char key;
- int i;
- if (XLookupString(event, (char *)&key, sizeof(key), (KeySym *)0,
- (XComposeStatus *) 0) > 0) {
-
- if (st->reset_countdown)
- st->reset_countdown = st->linger;
-
- switch (key) {
- case '<': st->dwell /= 2; if (st->dwell < 1) st->dwell = 1; return True;
- case '>': st->dwell *= 2; return True;
- case '[': st->settle /= 2; if (st->settle < 1) st->settle = 1; return True;
- case ']': st->settle *= 2; return True;
- case 'd': go_down(st); return True;
- case 'D': FlushBuffer(st); return True;
- case 'e':
- case 'E': FlushBuffer(st);
- st->dorecalc = (!st->dorecalc);
- if (st->dorecalc)
- recalc(st);
- else {
- st->maxexp = st->minlyap; st->minexp = -1.0 * st->minlyap;
- }
- redraw(st, st->exponents[st->frame], st->expind[st->frame], 1);
- return True;
- case 'f':
- /* case 'F': save_to_file(); return True;*/
- case 'i': if (st->stripe_interval > 0) {
- st->stripe_interval--;
- if (!mono_p) {
- init_color(st);
- }
- }
- return True;
- case 'I': st->stripe_interval++;
- if (!mono_p) {
- init_color(st);
- }
- return True;
- case 'K': if (st->minlyap > 0.05)
- st->minlyap -= 0.05;
- return True;
- case 'J': st->minlyap += 0.05;
- return True;
- case 'm': st->mapindex++;
- if (st->mapindex >= NUMMAPS)
- st->mapindex=0;
- st->map = Maps[st->mapindex];
- st->deriv = Derivs[st->mapindex];
- if (!st->aflag)
- st->min_a = amins[st->mapindex];
- if (!st->wflag)
- st->a_range = aranges[st->mapindex];
- if (!st->bflag)
- st->min_b = bmins[st->mapindex];
- if (!st->hflag)
- st->b_range = branges[st->mapindex];
- if (!st->Force)
- for (i=0;i<FUNCMAXINDEX;i++)
- st->Forcing[i] = st->mapindex;
- st->max_a = st->min_a + st->a_range;
- st->max_b = st->min_b + st->b_range;
- st->a_minimums[0] = st->min_a; st->b_minimums[0] = st->min_b;
- st->a_maximums[0] = st->max_a; st->b_maximums[0] = st->max_b;
- st->a_inc = st->a_range / (double)st->width;
- st->b_inc = st->b_range / (double)st->height;
- st->point.x = -1;
- st->point.y = 0;
- st->a = /*st->rubber_data.p_min = */st->min_a;
- st->b = /*st->rubber_data.q_min = */st->min_b;
-/* st->rubber_data.p_max = st->max_a;
- st->rubber_data.q_max = st->max_b;*/
- Clear(st);
- return True;
- case 'M': if (st->minlyap > 0.005)
- st->minlyap -= 0.005;
- return True;
- case 'N': st->minlyap += 0.005;
- return True;
- case 'p':
- case 'P': st->negative = (!st->negative);
- FlushBuffer(st); redraw(st, st->exponents[st->frame],
- st->expind[st->frame], 1);
- return True;
- case 'r': FlushBuffer(st); redraw(st, st->exponents[st->frame],
- st->expind[st->frame], 1);
- return True;
- case 'R': FlushBuffer(st); Redraw(st); return True;
- case 's':
- st->spinlength=st->spinlength/2;
-#if 0
- case 'S': if (!mono_p)
- Spin(st);
- st->spinlength=st->spinlength*2; return True;
-#endif
- case 'u': go_back(st); return True;
- case 'U': go_init(st); return True;
- case 'v':
- case 'V': print_values(st); return True;
- case 'W': if (st->numwheels < MAXWHEELS)
- st->numwheels++;
- else
- st->numwheels = 0;
- if (!mono_p) {
- init_color(st);
- }
- return True;
- case 'w': if (st->numwheels > 0)
- st->numwheels--;
- else
- st->numwheels = MAXWHEELS;
- if (!mono_p) {
- init_color(st);
- }
- return True;
- case 'x': Clear(st); return True;
- case 'X': Destroy_frame(st); return True;
- case 'z': Cycle_frames(st); redraw(st, st->exponents[st->frame],
- st->expind[st->frame], 1);
- return True;
-#if 0
- case 'Z': while (!XPending(st->dpy)) Cycle_frames(st);
- redraw(st, st->exponents[st->frame], st->expind[st->frame], 1);
- return True;
-#endif
- case 'q':
- case 'Q': exit(0); return True;
- case '?':
- case 'h':
- case 'H': print_help(st); return True;
- default: return False;
- }
- }
-
- return False;
-}
-
-/* Here's where we index into a color map. After the Lyapunov exponent is
- * calculated, it is used to determine what color to use for that point. I
- * suppose there are a lot of ways to do this. I used the following : if it's
- * non-negative then there's a reserved area at the lower range of the color
- * map that i index into. The ratio of some "minimum exponent value" and the
- * calculated value is used as a ratio of how high to index into this reserved
- * range. Usually these colors are dark red (see init_color). If the exponent
- * is negative, the same ratio (expo/minlyap) is used to index into the
- * remaining portion of the colormap (which is usually some light shades of
- * color or a rainbow wheel). The coloring scheme can actually make a great
- * deal of difference in the quality of the picture. Different colormaps bring
- * out different details of the dynamics while different indexing algorithms
- * also greatly effect what details are seen. Play around with this.
- */
-static int
-sendpoint(struct state *st, double expo)
-{
- double tmpexpo;
-
- if (st->maxcolor > MAXCOLOR)
- abort();
-
-#if 0
- /* The relationship st->minexp <= expo <= maxexp should always be true. This
- test enforces that. But maybe not enforcing it makes better pictures. */
- if (expo < st->minexp)
- expo = st->minexp;
- else if (expo > maxexp)
- expo = maxexp;
-#endif
-
- st->point.x++;
- tmpexpo = (st->negative) ? expo : -1.0 * expo;
- if (tmpexpo > 0) {
- if (!mono_p) {
- st->sendpoint_index = (int)(tmpexpo*st->lowrange/st->maxexp);
- st->sendpoint_index = ((st->sendpoint_index % st->lowrange) +
- st->startcolor);
- }
- else
- st->sendpoint_index = 0;
- }
- else {
- if (!mono_p) {
- st->sendpoint_index = (int)(tmpexpo*st->numfreecols/st->minexp);
- st->sendpoint_index = ((st->sendpoint_index % st->numfreecols)
- + st->mincolindex);
- }
- else
- st->sendpoint_index = 1;
- }
- BufferPoint(st, st->sendpoint_index, st->point.x, st->point.y);
- if (st->save) {
- if (st->frame > MAXFRAMES)
- abort();
- st->exponents[st->frame][st->expind[st->frame]++] = expo;
- }
- if (st->point.x >= st->width) {
- st->point.y++;
- st->point.x = 0;
- if (st->save) {
- st->b += st->b_inc;
- st->a = st->min_a;
- }
- if (st->point.y >= st->height)
- return FALSE;
- else
- return TRUE;
- }
- return TRUE;
-}
-
-
-static void
-resize(struct state *st)
-{
- Window r;
- int n, x, y;
- unsigned int bw, d, new_w, new_h;
-
- XGetGeometry(st->dpy,st->canvas,&r,&x,&y,&new_w,&new_h,&bw,&d);
- if ((new_w == st->width) && (new_h == st->height))
- return;
- st->width = new_w; st->height = new_h;
- XClearWindow(st->dpy, st->canvas);
-#ifdef BACKING_PIXMAP
- if (st->pixmap)
- XFreePixmap(st->dpy, st->pixmap);
- st->pixmap = XCreatePixmap(st->dpy, st->canvas, st->width, st->height, d);
-#endif
- st->a_inc = st->a_range / (double)st->width;
- st->b_inc = st->b_range / (double)st->height;
- st->point.x = -1;
- st->point.y = 0;
- st->run = 1;
- st->a = /*st->rubber_data.p_min = */st->min_a;
- st->b = /*st->rubber_data.q_min = */st->min_b;
-/* st->rubber_data.p_max = st->max_a;
- st->rubber_data.q_max = st->max_b;*/
- freemem(st);
- setupmem(st);
- for (n=0;n<MAXFRAMES;n++)
- if ((n <= st->maxframe) && (n != st->frame))
- st->resized[n] = 1;
- InitBuffer(st);
- Clear(st);
- Redraw(st);
-}
-
-static void
-redraw(struct state *st, double *exparray, int index, int cont)
-{
- int i, x_sav, y_sav;
-
- x_sav = st->point.x;
- y_sav = st->point.y;
-
- st->point.x = -1;
- st->point.y = 0;
-
- st->save=0;
- for (i=0;i<index;i++)
- sendpoint(st, exparray[i]);
- st->save=1;
-
- if (cont) {
- st->point.x = x_sav;
- st->point.y = y_sav;
- }
- else {
- st->a = st->point.x * st->a_inc + st->min_a;
- st->b = st->point.y * st->b_inc + st->min_b;
- }
- FlushBuffer(st);
-}
-
-static void
-Redraw(struct state *st)
-{
- FlushBuffer(st);
- st->point.x = -1;
- st->point.y = 0;
- st->run = 1;
- st->a = st->min_a;
- st->b = st->min_b;
- st->expind[st->frame] = 0;
- st->resized[st->frame] = 0;
-}
-
-static void
-recalc(struct state *st)
-{
- int i;
-
- st->minexp = st->maxexp = 0.0;
- for (i=0;i<st->expind[st->frame];i++) {
- if (st->exponents[st->frame][i] < st->minexp)
- st->minexp = st->exponents[st->frame][i];
- if (st->exponents[st->frame][i] > st->maxexp)
- st->maxexp = st->exponents[st->frame][i];
- }
-}
-
-static void
-Clear(struct state *st)
-{
- XClearWindow(st->dpy, st->canvas);
-#ifdef BACKING_PIXMAP
- XCopyArea(st->dpy, st->canvas, st->pixmap, st->Data_GC[0],
- 0, 0, st->width, st->height, 0, 0);
-#endif
- InitBuffer(st);
-}
-
-static void
-show_defaults(struct state *st)
-{
-
- printf("Width=%d Height=%d numcolors=%d settle=%d dwell=%d\n",
- st->width,st->height,st->numcolors,st->settle,st->dwell);
- printf("min_a=%f a_range=%f max_a=%f\n", st->min_a,st->a_range,st->max_a);
- printf("min_b=%f b_range=%f max_b=%f\n", st->min_b,st->b_range,st->max_b);
- printf("minlyap=%f minexp=%f maxexp=%f\n", st->minlyap,st->minexp,
- st->maxexp);
- exit(0);
-}
-
-#if 0
-static void
-CreateXorGC(struct state *st)
-{
- XGCValues values;
-
- values.foreground = st->foreground;
- values.function = GXxor;
- st->RubberGC = XCreateGC(st->dpy, st->canvas,
- GCForeground | GCFunction, &values);
-}
-
-static void
-StartRubberBand(struct state *st, image_data_t *data, XEvent *event)
-{
- XPoint corners[5];
-
- st->nostart = 0;
- data->rubber_band.last_x = data->rubber_band.start_x = event->xbutton.x;
- data->rubber_band.last_y = data->rubber_band.start_y = event->xbutton.y;
- SetupCorners(corners, data);
- XDrawLines(st->dpy, st->canvas, st->RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
-}
-
-static void
-SetupCorners(XPoint *corners, image_data_t *data)
-{
- corners[0].x = data->rubber_band.start_x;
- corners[0].y = data->rubber_band.start_y;
- corners[1].x = data->rubber_band.start_x;
- corners[1].y = data->rubber_band.last_y;
- corners[2].x = data->rubber_band.last_x;
- corners[2].y = data->rubber_band.last_y;
- corners[3].x = data->rubber_band.last_x;
- corners[3].y = data->rubber_band.start_y;
- corners[4] = corners[0];
-}
-
-static void
-TrackRubberBand(struct state *st, image_data_t *data, XEvent *event)
-{
- XPoint corners[5];
- int xdiff, ydiff;
-
- if (st->nostart)
- return;
- SetupCorners(corners, data);
- XDrawLines(st->dpy, st->canvas, st->RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
- ydiff = event->xbutton.y - data->rubber_band.start_y;
- xdiff = event->xbutton.x - data->rubber_band.start_x;
- data->rubber_band.last_x = data->rubber_band.start_x + xdiff;
- data->rubber_band.last_y = data->rubber_band.start_y + ydiff;
- if (data->rubber_band.last_y < data->rubber_band.start_y ||
- data->rubber_band.last_x < data->rubber_band.start_x)
- {
- data->rubber_band.last_y = data->rubber_band.start_y;
- data->rubber_band.last_x = data->rubber_band.start_x;
- }
- SetupCorners(corners, data);
- XDrawLines(st->dpy, st->canvas, st->RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
-}
-
-static void
-EndRubberBand(struct state *st, image_data_t *data, XEvent *event)
-{
- XPoint corners[5];
- XPoint top, bot;
- double delta, diff;
-
- st->nostart = 1;
- SetupCorners(corners, data);
- XDrawLines(st->dpy, st->canvas, st->RubberGC,
- corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
- if (data->rubber_band.start_x >= data->rubber_band.last_x ||
- data->rubber_band.start_y >= data->rubber_band.last_y)
- return;
- top.x = data->rubber_band.start_x;
- bot.x = data->rubber_band.last_x;
- top.y = data->rubber_band.start_y;
- bot.y = data->rubber_band.last_y;
- diff = data->q_max - data->q_min;
- delta = (double)top.y / (double)st->height;
- data->q_min += diff * delta;
- delta = (double)(st->height - bot.y) / (double)st->height;
- data->q_max -= diff * delta;
- diff = data->p_max - data->p_min;
- delta = (double)top.x / (double)st->width;
- data->p_min += diff * delta;
- delta = (double)(st->width - bot.x) / (double)st->width;
- data->p_max -= diff * delta;
- set_new_params(st, data);
-}
-
-static void
-set_new_params(struct state *st, image_data_t *data)
-{
- st->frame = (st->maxframe + 1) % MAXFRAMES;
- if (st->frame > st->maxframe)
- st->maxframe = st->frame;
- st->a_range = data->p_max - data->p_min;
- st->b_range = data->q_max - data->q_min;
- st->a_minimums[st->frame] = st->min_a = data->p_min;
- st->b_minimums[st->frame] = st->min_b = data->q_min;
- st->a_inc = st->a_range / (double)st->width;
- st->b_inc = st->b_range / (double)st->height;
- st->point.x = -1;
- st->point.y = 0;
- st->run = 1;
- st->a = st->min_a;
- st->b = st->min_b;
- st->a_maximums[st->frame] = st->max_a = data->p_max;
- st->b_maximums[st->frame] = st->max_b = data->q_max;
- st->expind[st->frame] = 0;
- Clear(st);
-}
-#endif
-
-static void
-go_down(struct state *st)
-{
- st->frame++;
- if (st->frame > st->maxframe)
- st->frame = 0;
- jumpwin(st);
-}
-
-static void
-go_back(struct state *st)
-{
- st->frame--;
- if (st->frame < 0)
- st->frame = st->maxframe;
- jumpwin(st);
-}
-
-static void
-jumpwin(struct state *st)
-{
- /*st->rubber_data.p_min =*/ st->min_a = st->a_minimums[st->frame];
- /*st->rubber_data.q_min =*/ st->min_b = st->b_minimums[st->frame];
- /*st->rubber_data.p_max =*/ st->max_a = st->a_maximums[st->frame];
- /*st->rubber_data.q_max =*/ st->max_b = st->b_maximums[st->frame];
- st->a_range = st->max_a - st->min_a;
- st->b_range = st->max_b - st->min_b;
- st->a_inc = st->a_range / (double)st->width;
- st->b_inc = st->b_range / (double)st->height;
- st->point.x = -1;
- st->point.y = 0;
- st->a = st->min_a;
- st->b = st->min_b;
- Clear(st);
- if (st->resized[st->frame])
- Redraw(st);
- else
- redraw(st, st->exponents[st->frame], st->expind[st->frame], 0);
-}
-
-static void
-go_init(struct state *st)
-{
- st->frame = 0;
- jumpwin(st);
-}
-
-static void
-Destroy_frame(struct state *st)
-{
- int i;
-
- for (i=st->frame; i<st->maxframe; i++) {
- st->exponents[st->frame] = st->exponents[st->frame+1];
- st->expind[st->frame] = st->expind[st->frame+1];
- st->a_minimums[st->frame] = st->a_minimums[st->frame+1];
- st->b_minimums[st->frame] = st->b_minimums[st->frame+1];
- st->a_maximums[st->frame] = st->a_maximums[st->frame+1];
- st->b_maximums[st->frame] = st->b_maximums[st->frame+1];
- }
- st->maxframe--;
- go_back(st);
-}
-
-static void
-InitBuffer(struct state *st)
-{
- int i;
-
- for (i = 0 ; i < st->maxcolor; ++i)
- st->Points.npoints[i] = 0;
-}
-
-static void
-BufferPoint(struct state *st, int color, int x, int y)
-{
- if (st->maxcolor > MAXCOLOR)
- abort();
-
- /* Guard against bogus color values. Shouldn't be necessary but paranoia
- is good. */
- if (color < 0)
- color = 0;
- else if (color >= st->maxcolor)
- color = st->maxcolor - 1;
-
- if (st->Points.npoints[color] == MAXPOINTS)
- {
- XDrawPoints(st->dpy, st->canvas, st->Data_GC[color],
- st->Points.data[color], st->Points.npoints[color],
- CoordModeOrigin);
-#ifdef BACKING_PIXMAP
- XDrawPoints(st->dpy, st->pixmap, st->Data_GC[color],
- st->Points.data[color], st->Points.npoints[color],
- CoordModeOrigin);
-#endif
- st->Points.npoints[color] = 0;
- }
- st->Points.data[color][st->Points.npoints[color]].x = x;
- st->Points.data[color][st->Points.npoints[color]].y = y;
- ++st->Points.npoints[color];
-}
-
-static void
-FlushBuffer(struct state *st)
-{
- int color;
-
- for (color = 0; color < st->maxcolor; ++color)
- if (st->Points.npoints[color])
- {
- XDrawPoints(st->dpy, st->canvas, st->Data_GC[color],
- st->Points.data[color], st->Points.npoints[color],
- CoordModeOrigin);
-#ifdef BACKING_PIXMAP
- XDrawPoints(st->dpy, st->pixmap, st->Data_GC[color],
- st->Points.data[color], st->Points.npoints[color],
- CoordModeOrigin);
-#endif
- st->Points.npoints[color] = 0;
- }
-}
-
-static void
-print_help(struct state *st)
-{
- printf("During run-time, interactive control can be exerted via : \n");
- printf("Mouse buttons allow rubber-banding of a zoom box\n");
- printf("< halves the 'dwell', > doubles the 'dwell'\n");
- printf("[ halves the 'settle', ] doubles the 'settle'\n");
- printf("D flushes the drawing buffer\n");
- printf("e or E recalculates color indices\n");
- printf("f or F saves exponents to a file\n");
- printf("h or H or ? displays this message\n");
- printf("i decrements, I increments the stripe interval\n");
- printf("KJMN increase/decrease minimum negative exponent\n");
- printf("m increments the map index, changing maps\n");
- printf("p or P reverses the colormap for negative/positive exponents\n");
- printf("r redraws without recalculating\n");
- printf("R redraws, recalculating with new dwell and settle values\n");
- printf("s or S spins the colorwheel\n");
- printf("u pops back up to the last zoom\n");
- printf("U pops back up to the first picture\n");
- printf("v or V displays the values of various settings\n");
- printf("w decrements, W increments the color wheel index\n");
- printf("x or X clears the window\n");
- printf("q or Q exits\n");
-}
-
-static void
-print_values(struct state *st)
-{
- int i;
- printf("\nminlyap=%f minexp=%f maxexp=%f\n",
- st->minlyap,st->minexp, st->maxexp);
- printf("width=%d height=%d\n",st->width,st->height);
- printf("settle=%d dwell=%d st->start_x=%f\n",
- st->settle,st->dwell, st->start_x);
- printf("min_a=%f a_rng=%f max_a=%f\n",
- st->min_a,st->a_range,st->max_a);
- printf("min_b=%f b_rng=%f max_b=%f\n",
- st->min_b,st->b_range,st->max_b);
- if (st->Rflag)
- printf("pseudo-random forcing\n");
- else if (st->force) {
- printf("periodic forcing=");
- for (i=0;i<st->maxindex;i++)
- printf("%d",st->forcing[i]);
- printf("\n");
- }
- else
- printf("periodic forcing=01\n");
- if (st->Force) {
- printf("function forcing=");
- for (i=0;i<st->funcmaxindex;i++) {
- printf("%d",st->Forcing[i]);
- }
- printf("\n");
- }
- printf("numcolors=%d\n",st->numcolors-1);
-}
-
-static void
-freemem(struct state *st)
-{
- int i;
- for (i=0;i<MAXFRAMES;i++)
- free(st->exponents[i]);
-}
-
-static void
-setupmem(struct state *st)
-{
- int i;
- for (i=0;i<MAXFRAMES;i++) {
- if((st->exponents[i]=
- (double *)malloc(sizeof(double)*st->width*(st->height+1)))==NULL){
- fprintf(stderr,"Error malloc'ing exponent array.\n");
- exit(-1);
- }
- }
-}
-
-static void
-setforcing(struct state *st)
-{
- int i;
- for (i=0;i<MAXINDEX;i++)
- st->forcing[i] = (random() > st->prob) ? 0 : 1;
-}
-
-/****************************************************************************/
-
-static void
-do_defaults (struct state *st)
-{
- int i;
-
- memset (st->expind, 0, sizeof(st->expind));
- memset (st->resized, 0, sizeof(st->resized));
-
- st->aflag = 0;
- st->bflag = 0;
- st->hflag = 0;
- st->wflag = 0;
- st->minexp = 0;
- st->mapindex = 0;
-
-# ifdef SIXTEEN_COLORS
- st->maxcolor=16;
- st->startcolor=0;
- st->color_offset=0;
- st->mincolindex=1;
- st->dwell=50;
- st->settle=25;
- st->xposition=128;
- st->yposition=128;
-# else /* !SIXTEEN_COLORS */
- st->maxcolor=256;
- st->startcolor=17;
- st->color_offset=96;
- st->mincolindex=33;
- st->dwell=100;
- st->settle=50;
-# endif /* !SIXTEEN_COLORS */
-
- st->maxindex = MAXINDEX;
- st->funcmaxindex = FUNCMAXINDEX;
- st->min_a=2.0;
- st->min_b=2.0;
- st->a_range=2.0;
- st->b_range=2.0;
- st->minlyap=1.0;
- st->max_a=4.0;
- st->max_b=4.0;
- st->numcolors=16;
- st->prob=0.5;
- st->numwheels=MAXWHEELS;
- st->negative=1;
- st->rgb_max=65000;
- st->nostart=1;
- st->stripe_interval=7;
- st->save=1;
- st->useprod=1;
- st->spinlength=256;
- st->run=1;
-
- for (i = 0; i < countof(st->forcing); i++)
- st->forcing[i] = (i & 1) ? 1 : 0;
-}
-
-static void
-do_preset (struct state *st, int builtin)
-{
- char *ff = 0;
- switch (builtin) {
- case 0:
- st->min_a = 3.75; st->aflag++;
- st->min_b = 3.299999; st->bflag++;
- st->a_range = 0.05; st->wflag++;
- st->b_range = 0.05; st->hflag++;
- st->dwell = 200;
- st->settle = 100;
- ff = "abaabbaaabbb";
- break;
-
- case 1:
- st->min_a = 3.8; st->aflag++;
- st->min_b = 3.2; st->bflag++;
- st->b_range = .05; st->hflag++;
- st->a_range = .05; st->wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 2:
- st->min_a = 3.4; st->aflag++;
- st->min_b = 3.04; st->bflag++;
- st->a_range = .5; st->wflag++;
- st->b_range = .5; st->hflag++;
- ff = "abbbbbbbbb";
- st->settle = 500;
- st->dwell = 1000;
- break;
-
- case 3:
- st->min_a = 3.5; st->aflag++;
- st->min_b = 3.0; st->bflag++;
- st->a_range = 0.2; st->wflag++;
- st->b_range = 0.2; st->hflag++;
- st->dwell = 600;
- st->settle = 300;
- ff = "aaabbbab";
- break;
-
- case 4:
- st->min_a = 3.55667; st->aflag++;
- st->min_b = 3.2; st->bflag++;
- st->b_range = .05; st->hflag++;
- st->a_range = .05; st->wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 5:
- st->min_a = 3.79; st->aflag++;
- st->min_b = 3.22; st->bflag++;
- st->b_range = .02999; st->hflag++;
- st->a_range = .02999; st->wflag++;
- ff = "bbbbbaaaaa";
- break;
-
- case 6:
- st->min_a = 3.7999; st->aflag++;
- st->min_b = 3.299999; st->bflag++;
- st->a_range = 0.2; st->wflag++;
- st->b_range = 0.2; st->hflag++;
- st->dwell = 300;
- st->settle = 150;
- ff = "abaabbaaabbb";
- break;
-
- case 7:
- st->min_a = 3.89; st->aflag++;
- st->min_b = 3.22; st->bflag++;
- st->b_range = .028; st->hflag++;
- st->a_range = .02999; st->wflag++;
- ff = "bbbbbaaaaa";
- st->settle = 600;
- st->dwell = 1000;
- break;
-
- case 8:
- st->min_a = 3.2; st->aflag++;
- st->min_b = 3.7; st->bflag++;
- st->a_range = 0.05; st->wflag++;
- st->b_range = .005; st->hflag++;
- ff = "abbbbaa";
- break;
-
- case 9:
- ff = "aaaaaabbbbbb";
- st->mapindex = 1;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 10:
- ff = "aaaaaabbbbbb";
- st->mapindex = 1;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 11:
- st->mapindex = 1;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 12:
- ff = "abbb";
- st->mapindex = 1;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 13:
- ff = "abbabaab";
- st->mapindex = 1;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 14:
- ff = "abbabaab";
- st->dwell = 800;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- /* #### -x 0.05 */
- st->min_a = 3.91; st->aflag++;
- st->a_range = 0.0899999999; st->wflag++;
- st->min_b = 3.28; st->bflag++;
- st->b_range = 0.35; st->hflag++;
- break;
-
- case 15:
- ff = "aaaaaabbbbbb";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 16:
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 17:
- ff = "abbb";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 18:
- ff = "abbabaab";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 19:
- st->mapindex = 2;
- ff = "aaaaaabbbbbb";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 20:
- st->mapindex = 2;
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 21:
- st->mapindex = 2;
- ff = "abbb";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- case 22:
- st->mapindex = 2;
- ff = "abbabaab";
- st->dwell = 400;
- st->settle = 200;
- st->minlyap = st->maxexp = ABS(-0.85);
- st->minexp = -1.0 * st->minlyap;
- break;
-
- default:
- abort();
- break;
- }
-
- if (ff) {
- char *ch;
- int bindex = 0;
- st->maxindex = strlen(ff);
- if (st->maxindex > MAXINDEX)
- usage(st);
- ch = ff;
- st->force++;
- while (bindex < st->maxindex) {
- if (*ch == 'a')
- st->forcing[bindex++] = 0;
- else if (*ch == 'b')
- st->forcing[bindex++] = 1;
- else
- usage(st);
- ch++;
- }
- }
-}
-
-
-static void *
-xlyap_init (Display *d, Window window)
-{
- struct state *st = (struct state *) calloc (1, sizeof(*st));
- XWindowAttributes xgwa;
- int builtin = -1;
- XGetWindowAttributes (d, window, &xgwa);
- st->dpy = d;
- st->width = xgwa.width;
- st->height = xgwa.height;
- st->visual = xgwa.visual;
- st->screen = xgwa.screen;
- st->cmap = xgwa.colormap;
-
- do_defaults(st);
- parseargs(st);
-
- if (get_boolean_resource(st->dpy, "randomize", "Boolean"))
- builtin = random() % NBUILTINS;
- else {
- char *s = get_string_resource(st->dpy, "builtin", "Integer");
- if (s && *s)
- builtin = atoi(s);
- if (s) free (s);
- }
-
- if (builtin >= 0)
- do_preset (st, builtin);
-
- st->background = BlackPixelOfScreen(st->screen);
- setupmem(st);
- init_data(st);
- if (!mono_p)
- st->foreground = st->startcolor;
- else
- st->foreground = WhitePixelOfScreen(st->screen);
-
- /*
- * Create the window to display the Lyapunov exponents
- */
- st->canvas = window;
- init_color(st);
-
-#ifdef BACKING_PIXMAP
- st->pixmap = XCreatePixmap(st->dpy, window, st->width, st->height,
- xgwa.depth);
-#endif
-/* st->rubber_data.band_cursor = XCreateFontCursor(st->dpy, XC_hand2);*/
-/* CreateXorGC(st);*/
- Clear(st);
-
- st->delay = get_integer_resource(st->dpy, "delay", "Delay");
- st->linger = get_integer_resource(st->dpy, "linger", "Linger");
- if (st->linger < 1) st->linger = 1;
-
- return st;
-}
-
-
-static unsigned long
-xlyap_draw (Display *dpy, Window window, void *closure)
-{
- struct state *st = (struct state *) closure;
- int i;
-
- if (!st->run && st->reset_countdown) {
- st->reset_countdown--;
- if (st->reset_countdown)
- return 1000000;
- else {
- do_defaults (st);
- do_preset (st, (random() % NBUILTINS));
- Clear (st);
- init_data(st);
- init_color(st);
- resize (st);
- st->frame = 0;
- st->run = 1;
- }
- }
-
- for (i = 0; i < 2000; i++)
- if (complyap(st) == TRUE)
- {
- st->run = 0;
- st->reset_countdown = st->linger;
- break;
- }
- return st->delay;
-}
-
-static void
-xlyap_reshape (Display *dpy, Window window, void *closure,
- unsigned int w, unsigned int h)
-{
- struct state *st = (struct state *) closure;
- resize(st);
-}
-
-static Bool
-xlyap_event (Display *dpy, Window window, void *closure, XEvent *event)
-{
- struct state *st = (struct state *) closure;
-
- switch(event->type)
- {
- case KeyPress:
- if (Getkey(st, &event->xkey))
- return True;
- break;
-#if 0
- case ButtonPress:
- StartRubberBand(st, &st->rubber_data, event);
- return True;
- case MotionNotify:
- TrackRubberBand(st, &st->rubber_data, event);
- return True;
- case ButtonRelease:
- EndRubberBand(st, &st->rubber_data, event);
- return True;
-#endif
- default:
- break;
- }
-
- if (screenhack_event_helper (dpy, window, event))
- {
- Clear(st);
- return True;
- }
-
- return False;
-}
-
-static void
-xlyap_free (Display *dpy, Window window, void *closure)
-{
- int i;
- struct state *st = (struct state *) closure;
-
- freemem (st);
-
-#ifdef BACKING_PIXMAP
- XFreePixmap (st->dpy, st->pixmap);
-#endif
-/* XFreeGC (st->dpy, st->RubberGC);*/
- for (i = 0; i < st->maxcolor; i++)
- XFreeGC (st->dpy, st->Data_GC[i]);
- if (st->outname) free (st->outname);
-
- free (st);
-}
-
-
-XSCREENSAVER_MODULE ("XLyap", xlyap)