Draw the Mandelbrot Set
#include <stdio.h> | |
#include <stdlib.h> | |
#include <complex.h> | |
#define MAX_X 384 | |
#define MAX_Y 216 | |
#define X_LOWER -2.5 | |
#define X_UPPER 1.0555555 | |
#define Y_LOWER -1 | |
#define Y_UPPER 1 | |
#define MAX_ITERATIONS 255 | |
/* Calculate the number of iterations a point takes to leave a bound. */ | |
int iterations(double cr, double ci, int max_it) { | |
// Create our initial numbers, c and z, along with a counter for iterations, i. | |
double complex z = 0 + 0*I; | |
double complex c = cr + ci*I; | |
int i = 0; | |
// Keep iterating z until: | |
// (a) z gets higher than our upper bound, or | |
// (b) we hit the maximum number of iterations | |
for (; i<max_it; i++) { | |
z = z*z + c; | |
if (cabs(z) > 4) | |
break; | |
} | |
return i; | |
} | |
/* Linearly map a value from one range into another. */ | |
double linmap(double val, double lower1, double upper1, double lower2, double upper2) { | |
return ((val - lower1) / (upper1 - lower1)) * (upper2 - lower2) + lower2; | |
} | |
/* Calculate the colour for coordinates (x, y) and write into color[]. */ | |
void get_color(int x, int y, int maxX, int maxY, char color[]) { | |
// Map the screen coordinates to the Mandelbrot coordinates. | |
double x1 = linmap(x, 0, maxX, X_LOWER, X_UPPER); | |
double y1 = linmap(y, 0, maxY, Y_LOWER, Y_UPPER); | |
int its = iterations(x1, y1, MAX_ITERATIONS); | |
// Map the number of iterations to a colour between 0 and 255. | |
char r = linmap(its, 0, MAX_ITERATIONS, 0, 255); | |
char g = r; | |
char b = g; | |
// Write the colours. | |
color[0] = r; | |
color[1] = g; | |
color[2] = b; | |
} | |
/* Write the header for a PPM file. */ | |
void write_header(FILE *fp, int dimx, int dimy) { | |
fprintf(fp, "P6\n"); // Write magic chars. | |
fprintf(fp, "%d %d\n", dimx, dimy); // Write width and height. | |
fprintf(fp, "255\n"); // Write max colour value. | |
} | |
/* Generate a Mandelbrot image. */ | |
void generate_file(int dimx, int dimy) { | |
// Create a file and write to it. | |
FILE *fp = fopen("mandelbrot.ppm", "wb"); | |
write_header(fp, dimx, dimy); | |
// For each coordinate, calculate its color then write to file. | |
char color[3]; | |
for (int j=0; j<dimy; ++j) | |
for (int i=0; i<dimx; ++i) | |
{ | |
get_color(i, j, dimx, dimy, color); | |
fwrite(color, 1, 3, fp); | |
} | |
// Close the file pointer to clean up. | |
fclose(fp); | |
} | |
int main(int argc, char *argv[]) { | |
// Grab our parameters from the system args. | |
int dimx = atoi(argv[1]); | |
int dimy = atoi(argv[2]); | |
// Write the file with the given resolution. | |
generate_file(dimx, dimy); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment