mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 00:42:51 +08:00

* Adding a dark mode * Adding reference for types to summary pages * Adding API Reference * Adding modifiers to methods/fields/etc * Minimizing files input * Caching a lot of the output pages * Cache only for each execution * Adding API references to existing docs
87 lines
2.3 KiB
C#
87 lines
2.3 KiB
C#
/*
|
|
Ported from: https://rosettacode.org/wiki/Mandelbrot_set#C.23
|
|
Licensed under GNU Free Documentation License 1.2
|
|
*/
|
|
|
|
using System;
|
|
using Spectre.Console;
|
|
|
|
namespace Canvas;
|
|
|
|
public static class Mandelbrot
|
|
{
|
|
private const double MaxValueExtent = 2.0;
|
|
|
|
private struct ComplexNumber
|
|
{
|
|
public double Real { get; }
|
|
public double Imaginary { get; }
|
|
|
|
public ComplexNumber(double real, double imaginary)
|
|
{
|
|
Real = real;
|
|
Imaginary = imaginary;
|
|
}
|
|
|
|
public static ComplexNumber operator +(ComplexNumber x, ComplexNumber y)
|
|
{
|
|
return new ComplexNumber(x.Real + y.Real, x.Imaginary + y.Imaginary);
|
|
}
|
|
|
|
public static ComplexNumber operator *(ComplexNumber x, ComplexNumber y)
|
|
{
|
|
return new ComplexNumber(x.Real * y.Real - x.Imaginary * y.Imaginary,
|
|
x.Real * y.Imaginary + x.Imaginary * y.Real);
|
|
}
|
|
|
|
public double Abs()
|
|
{
|
|
return Real * Real + Imaginary * Imaginary;
|
|
}
|
|
}
|
|
|
|
public static Spectre.Console.Canvas Generate(int width, int height)
|
|
{
|
|
var canvas = new Spectre.Console.Canvas(width, height);
|
|
|
|
var scale = 2 * MaxValueExtent / Math.Min(canvas.Width, canvas.Height);
|
|
for (var i = 0; i < canvas.Height; i++)
|
|
{
|
|
var y = (canvas.Height / 2 - i) * scale;
|
|
for (var j = 0; j < canvas.Width; j++)
|
|
{
|
|
var x = (j - canvas.Width / 2) * scale;
|
|
var value = Calculate(new ComplexNumber(x, y));
|
|
canvas.SetPixel(j, i, GetColor(value));
|
|
}
|
|
}
|
|
|
|
return canvas;
|
|
}
|
|
|
|
private static double Calculate(ComplexNumber c)
|
|
{
|
|
const int MaxIterations = 1000;
|
|
const double MaxNorm = MaxValueExtent * MaxValueExtent;
|
|
|
|
var iteration = 0;
|
|
var z = new ComplexNumber();
|
|
do
|
|
{
|
|
z = z * z + c;
|
|
iteration++;
|
|
} while (z.Abs() < MaxNorm && iteration < MaxIterations);
|
|
|
|
return iteration < MaxIterations
|
|
? (double)iteration / MaxIterations
|
|
: 0;
|
|
}
|
|
|
|
private static Color GetColor(double value)
|
|
{
|
|
const double MaxColor = 256;
|
|
const double ContrastValue = 0.2;
|
|
return new Color(0, 0, (byte)(MaxColor * Math.Pow(value, ContrastValue)));
|
|
}
|
|
}
|