Created
November 19, 2017 03:34
-
-
Save bedekelly/5f9fb5f836e14bd6586ccf4528ab3ba8 to your computer and use it in GitHub Desktop.
Draw the Mandelbrot Set
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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