/* Sequential Mandlebrot program */ #include #include #include #include #include #include #include #include #define X_RESN 800 /* x resolution */ #define Y_RESN 800 /* y resolution */ #define DELAY 10 /* delay factor: to make the program run slower and give more interesting timing result */ #define HOLDSCREEN 1 /* Time to show the final image on screen before terminate */ #define H_MAX 360 /* HSB color space constant */ #define S_MAX 256 #define L_MAX 256 #define RGBMAX 255 /* R,G, and B vary over 0->RGBMAX */ unsigned long HSLtoRGB(int H,int S,int L) { double fH = (double)(H) / H_MAX; double fS = (double)(S) / S_MAX; double fL = (double)(L) / L_MAX; double fR,fG,fB; double temp1,temp2; double Rtemp3,Gtemp3,Btemp3; int R,G,B; if (fS == 0.0) { fR = fB = fG = fL; } else { if (fL < 0.5) temp2 = fL * (1.0 + fS); else temp2 = fL + fS - fL * fS; temp1 = 2.0 * fL - temp2; Rtemp3 = fH + 1.0/3.0; Gtemp3 = fH; Btemp3 = fH - 1.0/3.0; if (Rtemp3 > 1.0) Rtemp3 -= 1.0; else if (Rtemp3 < 0.0) Rtemp3 += 1.0; if (Gtemp3 > 1.0) Gtemp3 -= 1.0; else if (Gtemp3 < 0.0) Gtemp3 += 1.0; if (Btemp3 > 1.0) Btemp3 -= 1.0; else if (Btemp3 < 0.0) Btemp3 += 1.0; if (6.0 * Rtemp3 < 1.0) fR = temp1+(temp2-temp1)*6.0*Rtemp3; else if (2.0 * Rtemp3 < 1.0) fR = temp2; else if (3.0 * Rtemp3 < 2.0) fR = temp1+(temp2-temp1)*((2.0/3.0)-Rtemp3)*6.0; else fR = temp1; if (6.0 * Gtemp3 < 1.0) fG = temp1+(temp2-temp1)*6.0*Gtemp3; else if (2.0 * Gtemp3 < 1.0) fG = temp2; else if (3.0 * Gtemp3 < 2.0) fG = temp1+(temp2-temp1)*((2.0/3.0)-Gtemp3)*6.0; else fG = temp1; if (6.0 * Btemp3 < 1.0) fB = temp1+(temp2-temp1)*6.0*Btemp3; else if (2.0 * Btemp3 < 1.0) fB = temp2; else if (3.0 * Btemp3 < 2.0) fB = temp1+(temp2-temp1)*((2.0/3.0)-Btemp3)*6.0; else fB = temp1; } R = (int)(fR * (double)(RGBMAX)); G = (int)(fG * (double)(RGBMAX)); B = (int)(fB * (double)(RGBMAX)); R = R & 0xFF; G = G & 0xFF; B = B & 0xFF; return (unsigned long)( (R << 16) + (G << 8) + B); } typedef struct complextype { double real, imag; } Compl; struct timeval starttime, stoptime, elapsetime; int main (int argc, char **argv) { Window win; /* initialization for a window */ unsigned int width, height, /* window size */ x, y, /* window position */ border_width, /*border width in pixels */ display_width, display_height, /* size of screen */ screen; /* which screen */ char *window_name = "Mandelbrot Set", *display_name = NULL; GC gc; unsigned long valuemask = 0; XGCValues values; Display *display; XSizeHints size_hints; Pixmap bitmap; XPoint points[800]; FILE *fp, *fopen (); char str[100]; int color; XSetWindowAttributes attr[1]; /* Mandlebrot variables */ int i, j, k; Compl z, c; double lengthsq, temp; /* precompute color value*/ unsigned long colorCache[H_MAX]; for (k = 0;k < H_MAX;k++) { double d,l; d = ((1.0 * k) / 359.0); d = (1.0 - d * d); l = (int)(d * 128.0); colorCache[k] = HSLtoRGB(k,204,l); } double center_x, center_y; double zoom; if (argc != 4) { printf("Usage: mandelbrot center_x center_y zoom_factor\n"); printf("center_x and center_y are between -2.0 to 2.0.\n"); printf("The top-right corner is (2.0, 2.0) and the bottom-left corner is (-2.0, -2.0)\n"); printf("The zoom_facter is greater than 1.0\n"); printf("Example: mandelbrot -1.76 0.0 80\n"); printf("Example: mandelbrot -.7451 .1125 2000\n"); printf("Example: mandelbrot -.7451 .1125 5000\n"); printf("Example: mandelbrot -.74541 .1125 1000000\n"); printf("Example: mandelbrot -.745415 .11251 10000000\n"); center_x = 0.0; center_y = 0.0; zoom = 1.0; } else { printf("%s %s %s\n",argv[1],argv[2],argv[3]); center_x = (double)atof(argv[1]); center_y = (double)atof(argv[2]); zoom = (double)atof(argv[3]); printf("center = %f,%f zoom = %f\n",center_x,center_y,zoom); } /* connect to Xserver */ if ( (display = XOpenDisplay (display_name)) == NULL ) { fprintf (stderr, "drawon: cannot connect to X server %s\n", XDisplayName (display_name) ); exit (-1); } /* get screen size */ screen = DefaultScreen (display); display_width = DisplayWidth (display, screen); display_height = DisplayHeight (display, screen); /* set window size */ width = X_RESN; height = Y_RESN; /* set window position */ x = 0; y = 0; /* create opaque window */ border_width = 4; win = XCreateSimpleWindow (display, RootWindow (display, screen), x, y, width, height, border_width, BlackPixel (display, screen), WhitePixel (display, screen)); size_hints.flags = USPosition|USSize; size_hints.x = x; size_hints.y = y; size_hints.width = width; size_hints.height = height; size_hints.min_width = 300; size_hints.min_height = 300; XSetNormalHints (display, win, &size_hints); XStoreName(display, win, window_name); /* create graphics context */ gc = XCreateGC (display, win, valuemask, &values); XSetBackground (display, gc, WhitePixel (display, screen)); XSetForeground (display, gc, BlackPixel (display, screen)); XSetLineAttributes (display, gc, 1, LineSolid, CapRound, JoinRound); attr[0].backing_store = Always; attr[0].backing_planes = 1; attr[0].backing_pixel = BlackPixel(display, screen); XChangeWindowAttributes(display, win, CWBackingStore | CWBackingPlanes | CWBackingPixel, attr); XMapWindow (display, win); XSync(display, 0); /* Calculate and draw points */ gettimeofday(&starttime, NULL); for(i=0; i < X_RESN; i++) for(j=0; j < Y_RESN; j++) { z.real = 0.0; z.imag = 0.0; c.real = ((double) j - 400.0)/200.0; /* scale factors for 800 x 800 window */ c.imag = -((double)i - 400.0)/200.0; c.real = c.real/zoom+center_x; c.imag = c.imag/zoom+center_y; k = 0; do { /* iterate for pixel color */ temp = z.real*z.real - z.imag*z.imag + c.real; z.imag = 2.0*z.real*z.imag + c.imag; z.real = temp; lengthsq = z.real*z.real+z.imag*z.imag; k++; } while (lengthsq < 4.0 && k < H_MAX * DELAY); k = (k >= H_MAX * DELAY) ? H_MAX-1 : (k % H_MAX); XSetForeground (display, gc, colorCache[k]); XDrawPoint (display, win, gc, j, i); } gettimeofday(&stoptime, NULL); elapsetime.tv_usec = stoptime.tv_usec - starttime.tv_usec; elapsetime.tv_sec = stoptime.tv_sec - starttime.tv_sec; if (elapsetime.tv_usec<0) { elapsetime.tv_usec+=1000000; elapsetime.tv_sec--; } printf("elapse time %d sec %d usec\n", elapsetime.tv_sec, elapsetime.tv_usec); XFlush (display); sleep (HOLDSCREEN); /* Program Finished */ }