Skip to content

Instantly share code, notes, and snippets.

@rdebath
Last active April 1, 2018 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdebath/a0156d544b51a27a8a201b9bb0f4aa77 to your computer and use it in GitHub Desktop.
Save rdebath/a0156d544b51a27a8a201b9bb0f4aa77 to your computer and use it in GitHub Desktop.
mandelbrot.c
/* See: https://stackoverflow.com/questions/16124127/improvement-to-my-mandelbrot-set-code */
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
unsigned char palette[48] = {
66, 30, 15,
25, 7, 26,
9, 1, 47,
4, 4, 73,
0, 7, 100,
12, 44, 138,
24, 82, 177,
57, 125, 209,
134, 181, 229,
211, 236, 248,
241, 233, 191,
248, 201, 95,
255, 170, 0,
204, 128, 0,
153, 87, 0,
106, 52, 3
};
void color(int red, int green, int blue, int bg)
{
if (bg) {
printf("\033[48;2;%d;%d;%dm", red, green, blue);
} else {
printf("\033[38;2;%d;%d;%dm", red, green, blue);
// printf("█"); // U+2588
printf("▄"); // U+2584
printf("\033[m");
}
}
int main(int argc, char *argv[])
{
int w = 80, h = 24, x, y;
double pixratio = 0.5;
//each iteration, it calculates: newz = oldz*oldz + p, where p is the current pixel, and oldz stars at the origin
double pr, pi; //real and imaginary part of the pixel p
double newRe, newIm, oldRe, oldIm; //real and imaginary parts of new and old z
double zoom = 1, moveX = -0.5, moveY = 0; //you can change these to zoom and change position
int maxIterations = 1000;//after how much iterations the function should stop
double xscale = (pixratio*w/h) / (0.5 * zoom * w);
double yscale = 1.0 / (0.5 * zoom * h);
clock_t begin, end;
double time_spent;
begin = clock();
#if 0
fprintf(stderr, "%f %f %f %f\n",
(0 - w / 2) * xscale + moveX, (0 - h / 2) * yscale + moveY,
((w-1) - w / 2) * xscale + moveX, ((h-1) - h / 2) * yscale + moveY
);
#endif
//loop through every pixel
for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
int y2;
for(y2=0; y2<2; y2++)
{
//calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values
pr = (x - w / 2) * xscale + moveX;
pi = (y - h / 2 + y2*0.5) * yscale + moveY;
newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0
//"i" will represent the number of iterations
int i;
//start the iteration process
for(i = 0; i < maxIterations; i++)
{
//remember value of previous iteration
oldRe = newRe;
oldIm = newIm;
//the actual iteration, the real and imaginary part are calculated
newRe = oldRe * oldRe - oldIm * oldIm + pr;
newIm = 2 * oldRe * oldIm + pi;
//if the point is outside the circle with radius 2: stop
if((newRe * newRe + newIm * newIm) > 4) break;
}
if(i == maxIterations || i == 0)
color(0, 0, 0, !y2); // black
else
{
#ifdef LOG2PAL
double z = sqrt(newRe * newRe + newIm * newIm);
int brightness = 256. * log2(1.75 + i - log2(log2(z))) / log2(maxIterations);
if (brightness<0) brightness = 0;
color(brightness, brightness, brightness, !y2);
#else
unsigned char * p = palette+(i&15)*3;
color(p[0], p[1], p[2], !y2);
#endif
}
}
}
printf("\n");
}
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
// fprintf(stderr,"Elapsed time: %.2lf seconds.\n", time_spent);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment