/* NAME
* henwarp - warps a square into the phase space of the Henon system
* NOTES
* None.
* MISCELLANY
* You may wish to try this with a small length for the size of
* square and watch how the resulting plot changes as you slowly
* increase the value passed to the -count option starting at
* zero. The square will slowly spread out and converge to the
* attractor of the system.
*
* The method for choosing the viewable region may seem
* counter-intuitive at first, but it has some nice properties. In
* particular, selecting the exact (x, y) coordinates for the
* upper-left corner and only selecting the lower right y coordinate
* forces both the x and y scales to be identical since all scales
* are uniquely determined by these values along with the plot
* width and height. If you then change the width or height of the
* plot, the relative scales will still match up. The options for
* making a box work similarly.
* BUGS
* The length of the square is in pixels and works best if it is
* an odd value. With even numbered values it can produce a gap
* in the plot for small values supplied with the -count option.
*
* No sanity checks are performed to make sure that any of the
* options make sense.
* AUTHOR
* Copyright (c) 1997, Gary William Flake.
*
* Permission granted for any use according to the standard GNU
* ``copyleft'' agreement provided that the author's comments are
* neither modified nor removed. No warranty is given or implied.
*/
#include
#include
#include
#include "misc.h"
int width = 480, height = 480, len = 301, swap = 1, count = 1;
int invert = 0, mag = 1;
double A = 1.29, B = 0.3, ulx = -1.75, uly = 1.75, lly = -1.75;
char *term = NULL;
char help_string[] = "\
A square (initially centered about the origin) is transformed by the Henon \
system, which is described by the equation x(t+1) = A - x(t)^2 + B * \
x(t - 1), a fixed number of times according to the specified parameters. \
";
OPTION options[] = {
{ "-width", OPT_INT, &width, "Width of the plot in pixels." },
{ "-height", OPT_INT, &height, "Height of the plot in pixels." },
{ "-swap", OPT_SWITCH, &swap, "Swap the x and y axis." },
{ "-len", OPT_INT, &len, "Length of edge of square." },
{ "-count", OPT_INT, &count, "Number of transformations." },
{ "-A", OPT_DOUBLE, &A, "Value of the A parameter." },
{ "-B", OPT_DOUBLE, &B, "Value of the B parameter." },
{ "-ulx", OPT_DOUBLE, &ulx, "Upper-left corner x-coordinate." },
{ "-uly", OPT_DOUBLE, &uly, "Upper-left corner y-coordinate." },
{ "-lly", OPT_DOUBLE, &lly, "Lower-left corner y-coordinate." },
{ "-inv", OPT_SWITCH, &invert, "Invert all colors?" },
{ "-mag", OPT_INT, &mag, "Magnification factor." },
{ "-term", OPT_STRING, &term, "How to plot points." },
{ NULL, OPT_NULL, NULL, NULL }
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int main(int argc, char **argv)
{
extern int plot_mag;
extern int plot_inverse;
int i, j, k;
double x, t, y, a, b, lrx, xinc, yinc;
double **gridx, **gridy;
get_options(argc, argv, options, help_string);
/* Force the length to be odd. */
len += (len / 2 * 2 == len);
/* Calculate the scaling paramters. */
lrx = ulx + ((uly - lly) / (height - 1)) * (width - 1);
xinc = (lrx - ulx) / (width - 1);
yinc = (uly - lly) / (height - 1);
/* Allocate a grid of points and store the points in the square
* centered about the origin.
*/
gridx = xmalloc(sizeof(double *) * len);
gridy = xmalloc(sizeof(double *) * len);
for(i = 0; i < len; i++) {
gridx[i] = xmalloc(sizeof(double) * len);
gridy[i] = xmalloc(sizeof(double) * len);
for(j = 0; j < len; j++) {
gridx[i][j] = xinc * (-0.5 * len + j);
gridy[i][j] = yinc * (-0.5 * len + i);
}
}
plot_mag = mag;
plot_inverse = invert;
plot_init(width, height, 2, term);
plot_set_range(ulx, lrx, lly, uly);
plot_set_all(0);
/* For each grid point ... */
for(i = 0; i < len; i++) {
for(j = 0; j < len; j++) {
/* Tranform the point a fixed number of times and plot it. */
x = gridx[i][j]; y = gridy[i][j];
for(k = 0; k < count; k++) {
t = A - x*x + B * y; y = x; x = t;
}
a = swap ? y : x; b = swap ? x : y;
plot_point(a, b, 1);
}
}
plot_finish();
exit(0);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */