Skip to content

Instantly share code, notes, and snippets.

@LeopoldTal
Created September 1, 2018 21:58
Show Gist options
  • Save LeopoldTal/2aa79947c4cab728402c4054d6733254 to your computer and use it in GitHub Desktop.
Save LeopoldTal/2aa79947c4cab728402c4054d6733254 to your computer and use it in GitHub Desktop.
Mandelbrot set ASCII art
/*
* Mandelbrot set ascii art
*/
#include <stdio.h>
#include <string.h>
/* Params */
//TODO: these should be command line arguments
const int COLUMNS = 151, LINES = 53;
const float CENTRE_X = -0.6, CENTRE_Y = 0;
const float STEP = 0.045; // in y direction
// threshold to accept a point as in the set
// increase this when the step is small (high zoom)
const int MAX_ITERS = 200;
// points not in the set are shaded by how fast they diverge
// cyclic list of chars to use for different divergence speeds
const char palette[] = "Patrick!<3";
/*
* Determines whether a point is in the Mandelbrot set
* params: float ptX, float ptY: x and y coords of the point
* returns: int number of iterations to reject the point (MAX_ITERS if accepted)
*/
int getRejectionIters(const float ptX, const float ptY)
{
float re = 0, im = 0, reSq = 0, imSq = 0;
int nbIters = 0;
// iterate z <- z^2 + pt
// until |z|>2 (diverging) or the point is accepted
while (imSq + reSq <= 4 && nbIters < MAX_ITERS)
{
im = 2*re*im + ptY;
re = reSq - imSq + ptX;
imSq = im*im;
reSq = re*re;
nbIters++;
}
return nbIters;
}
/*
* Writes a single character representing a point
* params: float ptX, float ptY: x and y coords of the point
*/
void drawPoint(const float ptX, const float ptY)
{
int rejectionIters;
rejectionIters = getRejectionIters(ptX, ptY);
if (rejectionIters >= MAX_ITERS) // point in set
{
printf(" ");
}
else // point not in set; shade by divergence speed
{
printf("%c", palette[(rejectionIters - 1) % strlen(palette)]);
}
}
int main()
{
// character aspect ratio is 2:1 on my terminal
const float STEP_X = STEP / 2, STEP_Y = STEP;
int curCol, curLine;
float ptX, ptY;
// iterating over point coords directly risks rounding errors
for (curLine = 0 ; curLine < LINES ; curLine++) // y-coord, decreasing
{
ptY = CENTRE_Y + (0.5 * LINES - curLine - 0.5) * STEP_Y;
for (curCol = 0 ; curCol < COLUMNS ; curCol++) // x-coord, increasing
{
ptX = CENTRE_X - (0.5 * COLUMNS - curCol - 0.5) * STEP_X;
drawPoint(ptX, ptY);
}
printf("\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment