diff options
author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
---|---|---|
committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/xlyap.c | |
parent | Delete pre-6.00 files (diff) | |
download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip |
Diffstat (limited to 'hacks/xlyap.c')
-rw-r--r-- | hacks/xlyap.c | 1938 |
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) |