Created
February 26, 2025 19:10
-
-
Save andrewstellman/758c08d082008297f30857c7481a68dd to your computer and use it in GitHub Desktop.
Animated console Mandelbrot in C#
This file contains hidden or 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
// 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