// fractal.cxx // Program to draw the Mandelbrot fractal. #include // Provides the winbgim library #include // Provides toupper function #include // Provides cin and cout #include // Provides the complex type using namespace std; // Constant declarations const int WINDOW_SIZE = 600; // Width and height of the window in pixels const double RADIUS = 2.0; // Radius of the circle that defines the in group const int MANY_COLORS = 47; // Number of colors in the table const int TABLE[MANY_COLORS][3] = { { 100, 0, 0}, // Dark Red { 230, 130, 0}, // Light Orange { 0, 60, 0}, // Real Dark Green { 20, 20, 200}, // Blue { 130, 130, 235}, // Light Blue { 200, 200, 20}, // Yellow { 252, 252, 84}, // Yellow { 252, 252, 84}, // Yellow { 252, 252, 84}, // Yellow { 0, 0, 0}, // Black { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 0, 0}, // Red { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 255, 60, 0}, // Orange { 20, 20, 200}, // Blue { 230, 230, 255}, // Light Blue { 20, 20, 200}, // Blue { 230, 230, 255}, // Light Blue { 20, 20, 200}, // Blue { 230, 230, 255}, // Light Blue { 20, 20, 200}, // Blue { 230, 230, 255}, // Light Blue { 20, 20, 200}, // Blue { 230, 230, 255}, // Light Blue { 20, 20, 200}, // Blue { 20, 150, 255}, // Light blue { 20, 20, 200}, // Blue { 0, 0, 0}, // Black { 0, 0, 0} // Black //{ 240, 243, 243}, // Near white //{ 240, 243, 243} // Near white }; void change_controls (char& command, double& centerx, double& centery, double& half_size); // Wait for a key stroke or mouse click, and then change the // values of the four control variables. void draw_fractal(double cx, double cy, double half_side); // This draws part of a fractal. The center is at // (cx, cy) and half_side is the length of half the side // of the square that is drawn. int pixel_color(complex p); // Calculates the color to put at the specified col and row. int main( ) { char command; // A key from the keyboard double centerx = 0; // X cartesian coordinate of center double centery = 0; // Y cartesian coordinate of center double half_size = 2; // Half the size of window in cartesian initwindow(WINDOW_SIZE, WINDOW_SIZE); do { draw_fractal(centerx, centery, half_size); change_controls(command, centerx, centery, half_size); } while (command != 'Q'); return 0; } void change_controls (char& command, double& centerx, double& centery, double& half_size) { const int WAIT = 100; // Time to delay when there is no keystroke int pixelx, pixely; // Location of the mouse click // Wait for a key stroke or mouse click while (!kbhit( ) && !ismouseclick(WM_LBUTTONUP)) { delay(WAIT); } if (kbhit( )) { // Deal with the key stroke command = toupper(getch()); switch (command) { case '+': half_size /= 2; break; case '-': half_size *= 2; break; case '.': cin >> half_size >> centerx >> centery; } } else { // Deal with the mouse click getmouseclick(WM_LBUTTONUP, pixelx, pixely); centerx = (2*half_size/WINDOW_SIZE) * pixelx + (centerx - half_size); centery = -(2*half_size/WINDOW_SIZE) * pixely + (centery + half_size); } cout << half_size << ' ' << centerx << ' ' << centery << endl; } void draw_fractal(double cx, double cy, double half_side) { int row, col; // The pixel numbers of the row and column double realx, realy; // The coordinates in the complex plane complex p; // The point as a complex number row = 0; while (row < WINDOW_SIZE) { // Color all the pixels in this row... col = 0; while (col < WINDOW_SIZE) { // Color the pixel at location (col, row) realx = (2.0*half_side/WINDOW_SIZE)*col + (cx-half_side); realy = -(2.0*half_side/WINDOW_SIZE)*row + (cy+half_side); p = complex(realx, realy); putpixel(col, row, pixel_color(p)); col++; } row++; } } int pixel_color(complex p) { const int LIMIT = (MANY_COLORS-1) * 10 - 1; complex start = p; int count = 0; int lower, upper, tenths; int answer; while (count < LIMIT && abs(p) < RADIUS) { p = p*p + start; count++; } // Create a color that depends on the number of jumps taken. // Example: If 123 jumps were taken, then the color created is 3/10ths // of the way between color 12 and color 13. lower = count / 10; // A color from 0 to MANY_COLORS-2 upper = lower + 1 ; // The next color up tenths = count % 10; // How far are we between lower and upper? answer = COLOR( TABLE[lower][0] + tenths * (TABLE[upper][0] - TABLE[lower][0]) / 10, TABLE[lower][1] + tenths * (TABLE[upper][1] - TABLE[lower][1]) / 10, TABLE[lower][2] + tenths * (TABLE[upper][2] - TABLE[lower][2]) / 10 ); return answer; }