Skip to content

Instantly share code, notes, and snippets.

@andrewstellman
Created February 26, 2025 19:10
Show Gist options
  • Save andrewstellman/758c08d082008297f30857c7481a68dd to your computer and use it in GitHub Desktop.
Save andrewstellman/758c08d082008297f30857c7481a68dd to your computer and use it in GitHub Desktop.
Animated console Mandelbrot in C#
// Parse command line arguments for width, height, frames, and maxIterations
int width = 80; // Default width
int height = 40; // Default height
int frames = 100; // Default number of frames
int maxIterations = 100; // Default max iterations
// Check if args is not null
if (args != null)
{
// Parse width if provided
if (args.Length > 0 && int.TryParse(args[0], out int parsedWidth) && parsedWidth > 0)
{
width = parsedWidth;
}
// Parse height if provided
if (args.Length > 1 && int.TryParse(args[1], out int parsedHeight) && parsedHeight > 0)
{
height = parsedHeight;
}
// Parse frames if provided
if (args.Length > 2 && int.TryParse(args[2], out int parsedFrames) && parsedFrames > 0)
{
frames = parsedFrames;
}
// Parse maxIterations if provided
if (args.Length > 3 && int.TryParse(args[3], out int parsedIterations) && parsedIterations > 0)
{
maxIterations = parsedIterations;
}
}
// Zoom target coordinates (interesting area of the Mandelbrot set)
double targetX = -0.7436447860;
double targetY = 0.1318252536;
// Initial view coordinates
double xMin = -2.0;
double xMax = 1.0;
double yMin = -1.0;
double yMax = 1.0;
// Animation parameters
double zoomFactor = 0.9;
for (int frame = 0; frame < frames; frame++)
{
// Clear console before drawing new frame
Console.Clear();
// Calculate actual zoom level compared to original view
double originalRangeX = 3.0; // -2.0 to 1.0
double originalRangeY = 2.0; // -1.0 to 1.0
double currentRangeX = xMax - xMin;
double currentRangeY = yMax - yMin;
double actualZoomLevel = originalRangeX / currentRangeX;
// Display frame information
Console.WriteLine($"Frame {frame + 1}/{frames} - Zoom level: {actualZoomLevel:F2}x - Max iterations: {maxIterations}");
// Draw current frame
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
double x0 = xMin + (xMax - xMin) * col / width;
double y0 = yMin + (yMax - yMin) * row / height;
double x = 0;
double y = 0;
int iteration = 0;
while (x*x + y*y < 4 && iteration < maxIterations)
{
double xTemp = x*x - y*y + x0;
y = 2*x*y + y0;
x = xTemp;
iteration++;
}
// Choose a character based on how quickly the point escaped
char displayChar = ' ';
if (iteration == maxIterations)
displayChar = '#'; // Point is in the set
else if (iteration > maxIterations * 0.75)
displayChar = '@';
else if (iteration > maxIterations * 0.5)
displayChar = '*';
else if (iteration > maxIterations * 0.25)
displayChar = '+';
else if (iteration > maxIterations * 0.1)
displayChar = '.';
Console.Write(displayChar);
}
Console.WriteLine();
}
// Adjust the boundaries to zoom in toward target
double rangeX = xMax - xMin;
double rangeY = yMax - yMin;
xMin = targetX - (rangeX * zoomFactor) / 2;
xMax = targetX + (rangeX * zoomFactor) / 2;
yMin = targetY - (rangeY * zoomFactor) / 2;
yMax = targetY + (rangeY * zoomFactor) / 2;
// Pause between frames to make animation visible
Thread.Sleep(100);
// Increase max iterations slightly as we zoom in to reveal more detail
int initialMaxIterations = maxIterations;
if (frame % 10 == 0 && maxIterations < initialMaxIterations * 5)
{
maxIterations += initialMaxIterations / 10;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment