Path: utzoo!mnetor!uunet!lll-winken!lll-tis!mordor!sri-spam!ames!pasteur!ucbvax!decwrl!nsc!daisy!turner From: turner@daisy.UUCP (D'arc Angel) Newsgroups: comp.windows.x Subject: Re: Mandelbrot? Message-ID: <1132@daisy.UUCP> Date: 10 May 88 13:30:12 GMT References: <16823@cornell.UUCP> Reply-To: turner@daisy.UUCP (D'arc Angel) Distribution: comp Organization: The Houses of the Holy Lines: 342 I don't know how good this is..... #define DEBUG 0 #include#include #include #define MAX_COLORS 6 Display *display; Window window; int screen; extern int optind; extern char *optarg, getopt(); int cycling; main (argc, argv) int argc; char *argv[]; { int colors[MAX_COLORS+1]; int ncolors; int width; int height; window = winit (argc, argv, &width, &height); XSync(display, DEBUG); ncolors = set_colors (colors); make_fractal (window, width, height, colors, ncolors); if(cycling) cycle_colors (colors, ncolors); pause (); uninit (window); exit (0); } winit (argc, argv, width, height) int argc; char *argv[]; int *width; int *height; { XWindowAttributes window_attr; int i; char *hostname = NULL; char *geometry = NULL; int geomx, geomy, geomw, geomh; char c; geomx = 0; geomy = 0; geomw = 256; geomh = 256; /* defaults */ cycling = 1; while ((c = getopt(argc, argv, "g:d:c")) != EOF) switch (c) { case 'g': geometry = optarg; XParseGeometry(geometry, &geomx, &geomy, &geomw, &geomh); break; case 'd': hostname = optarg; break; case 'c': /* turn off cycling */ cycling = 0; break; default: usage(); } if ((display = XOpenDisplay (hostname)) == NULL) { printf ("%s: Unable to connect to display.\n", argv[0]); exit (1); } screen = DefaultScreen(display); if ((window = XCreateSimpleWindow (display, RootWindow(display, screen), geomx, geomy, geomw, geomh, 5, BlackPixel(display, screen), WhitePixel(display, screen))) == NULL) { printf ("%s: Unable to create window.\n", argv[0]); exit (1); } XGetWindowAttributes(display, window, &window_attr); *width = window_attr.width; *height = window_attr.height; return (window); } int set_colors (colors) int colors[]; { static char *name[] = {"Red", "Yellow", "Green", "Cyan", "Blue", "Magenta", "Black"}; XColor hw_def; XColor exact_def; Colormap cmap; int ncolors; int planes; int i; cmap = DefaultColormap(display, 0); for (ncolors = 6; ncolors >= 0; ncolors--) if (XAllocColorCells (display, cmap, 0, &planes, 0, colors, ncolors+1)) break; name[ncolors] = name[6]; for (i = 0; i <= ncolors; i++) { XAllocNamedColor (display, cmap, name[i], &hw_def, &exact_def); exact_def.pixel = colors[i]; XStoreColors (display, cmap, &exact_def, 1); } return (ncolors); } cycle_colors (colors, ncolors) int colors[]; int ncolors; { static char *name[] = {"Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"}; XColor hw_def; XColor exact_def[6]; Colormap cmap; int ist; int i; cmap = DefaultColormap(display, 0); for (i = 0; i < ncolors; i++) XAllocNamedColor (display, cmap, name[i], &hw_def, &exact_def[i]); for (ist = 0; ; ist = (ist + ncolors - 1) % ncolors) { for (i = 0; i < ncolors; i++) { exact_def[i].pixel = colors[(ist + i) % ncolors]; XStoreColors (display, cmap, &exact_def[i], 1); } } } make_fractal (window, max_pixels_x, max_pixels_y, colors, ncolors) Window window; int max_pixels_x; int max_pixels_y; int *colors; int ncolors; { static GC gc = NULL; XGCValues values; unsigned long valuemask; register int ix; register int iy; register int i; register double x; register double y; register double yl; register double x2; register double y2; static int max_iterations = 1000; static double max_value = 10.0; static double xcenter = 0.0; static double ycenter = 0.0; static double width = 2.0; static double height = 2.4; static double p = 0.32; static double q = 0.043; double min_x; double max_x; double min_y; double max_y; double pixwd; double pixht; int rows; int iclr; int mirror; if ((width / (double) max_pixels_x) > (height / (double) max_pixels_y)) height = width * ((double) max_pixels_y / (double) max_pixels_x); else width = height * ((double) max_pixels_x / (double) max_pixels_y); check_values (&max_iterations, &xcenter, &ycenter, &width, &height, &max_value, &p, &q); mirror = ((xcenter == 0.0) && (ycenter == 0.0)); if ((width / (double) max_pixels_x) > (height / (double) max_pixels_y)) height = width * ((double) max_pixels_y / (double) max_pixels_x); else width = height * ((double) max_pixels_x / (double) max_pixels_y); max_x = xcenter + width / 2.0; min_x = xcenter - width / 2.0; max_y = ycenter + height / 2.0; min_y = ycenter - height / 2.0; rows = (mirror ? (max_pixels_y + 1) / 2 : max_pixels_y); pixwd = (max_x - min_x) / ((double) (max_pixels_x-1)); pixht = (max_y - min_y) / ((double) (max_pixels_y-1)); XMapWindow (display, window); for (iy = 0; iy < rows; iy++) { yl = pixht * (double) iy + min_y; for (ix = 0; ix < max_pixels_x; ix++) { x = pixwd * (double) ix + min_x; y = yl; for (i = 0; i < max_iterations; i++) { x2 = x * x; y2 = y * y; if (x2 + y2 > max_value) break; y = ((double) 2.0) * x * y + q; x = x2 - y2 + p; } iclr = ((i < max_iterations) ? i % ncolors : ncolors); if(gc == NULL) gc = XCreateGC(display, window, 0, &values); XSetFillStyle(display, gc, FillSolid); XSetForeground(display, gc, colors[iclr]); XFillRectangle(display, window, gc, ix, max_pixels_y-iy-1, 1, 1); if (mirror) XFillRectangle(display, window, gc, max_pixels_x-ix-1, iy, 1, 1); } } } uninit (window) Window window; { XUnmapWindow (window); } check_values (max_iterations, xcenter, ycenter, width, height, max_value, p, q) int *max_iterations; double *xcenter; double *ycenter; double *width; double *height; double *max_value; double *p; double *q; { static struct {char *desc; char *fmt; char *addr;} pardef[] = {{"Maximum iterations:", "%d", (char *) 0}, {"Maximum value: ", "%lf", (char *) 0}, {"X Center: ", "%lf", (char *) 0}, {"Y Center: ", "%lf", (char *) 0}, {"Width: ", "%lf", (char *) 0}, {"Height: ", "%lf", (char *) 0}, {"P: ", "%lf", (char *) 0}, {"Q: ", "%lf", (char *) 0}}; int field; int ndx; int end; char resp[256]; char format[256]; pardef[0].addr = (char *) max_iterations; pardef[1].addr = (char *) max_value; pardef[2].addr = (char *) xcenter; pardef[3].addr = (char *) ycenter; pardef[4].addr = (char *) width; pardef[5].addr = (char *) height; pardef[6].addr = (char *) p; pardef[7].addr = (char *) q; do { printf ("\n\n"); for (ndx = 0; ndx < sizeof (pardef) / sizeof (*pardef); ndx++) { sprintf (format, "%4d. %s %s \n", ndx + 1, pardef[ndx].desc, pardef[ndx].fmt); if (!strcmp (pardef[ndx].fmt, "%lf")) printf (format, *((double *) pardef[ndx].addr)); else if (!strcmp (pardef[ndx].fmt, "%d")) printf (format, *((int *) pardef[ndx].addr)); else if (!strcmp (pardef[ndx].fmt, "%s")) printf (format, (char *) pardef[ndx].addr); } printf ("\n\nWhat do you want to change: "); end = !gets (resp); if (!end) end = !*resp; if (!end) { sscanf (resp, "%d", &field); if ((field > 0) && (field <= sizeof (pardef) / sizeof (*pardef))) { field--; printf ("\n\n%s ", pardef[field].desc); if (gets (resp)) sscanf (resp, pardef[field].fmt, pardef[field].addr); } } } while (!end); } usage() { fprintf(stderr, "Usage is:\n"); fprintf(stderr, "\tXFractal [-d displayname] [-g geometry] [-c] [-h]\n"); fprintf(stderr, "Where:\n"); fprintf(stderr, "-c\t\tdo not cycle colors when done drawing\n"); fprintf(stderr, "-h\t\ttype this message\n"); fprintf(stderr, "\n"); fprintf(stderr, "Note: to turn off the mirroring of the image around the X \n"); fprintf(stderr, "\taxis, select a center (items 3 and 4) other than 0,0\n"); exit(1); } -- Laissez les bons temps rouler - Queen Ida ...{decwrl|ucbvax}!imagen!atari!daisy!turner (James M. Turner) Daisy Systems, 700 E. Middlefield Rd, P.O. Box 7006, Mountain View CA 94039-7006. (415)960-0123