Skip to content

Instantly share code, notes, and snippets.

@GuyInGrey
Created March 17, 2021 19:10
Show Gist options
  • Save GuyInGrey/59ce800f7f7ea831793aa409c6b08890 to your computer and use it in GitHub Desktop.
Save GuyInGrey/59ce800f7f7ea831793aa409c6b08890 to your computer and use it in GitHub Desktop.
using System;
using SixLabors.ImageSharp;
using SixLaborsRgba32 = SixLabors.ImageSharp.PixelFormats.Rgba32;
namespace MandelbrotCPUTest
{
class Program
{
static void Main()
{
Console.WriteLine("Starting...");
var i = Render(new[] { -2.25f, -1.5f, 0.75f, 1.5f }, 2f, 500, 500, 50);
i.Save("test.png");
Console.WriteLine("Done!");
Console.Read();
}
public static Image<SixLaborsRgba32> Render(float[] viewport /*size 4*/, float power, int width, int height, int maxIterations)
{
var image = new Image<SixLaborsRgba32>(width, height);
for (var y = 0; y < height; y++)
{
for (var x = 0; x < width; x++)
{
var c = new Complex(
Map(x, 0, width, viewport[0], viewport[2]),
Map(y, 0, height, viewport[1], viewport[3]));
var z = new Complex(0, 0);
var i = 0;
while (Complex.Abs(z) <= 2 && i < maxIterations)
{
z = Complex.Pow(z, new Complex(power, 0)) + c;
i++;
}
float final;
if (i == maxIterations) { final = maxIterations; }
else
{
final = (float)(i + 1 - Math.Log(Math.Log(Complex.Abs(z))) / Math.Log(2));
}
var color = (byte)((final / maxIterations) * 255);
image[x, y] = Color.FromRgba(color, color, color, 255);
}
}
return image;
}
public static float Lerp(float a, float b, float t) =>
a * (1 - t) + b * t;
public static float Map(float val, float a1, float b1, float a2, float b2) =>
Lerp(a2, b2, (val - a1) / (b1 - a1));
}
public class Complex
{
public float Real; // X
public float Imaginary; // Y
public Complex(float r, float i) { Real = r; Imaginary = i; }
public static Complex operator +(Complex a, Complex b) =>
new(a.Real + b.Real, a.Imaginary + b.Imaginary);
public static float Abs(Complex value)
{
return (float)Math.Sqrt(value.Real * value.Real + value.Imaginary * value.Imaginary);
}
public static Complex Pow(Complex value, Complex power)
{
if (power.Real == 0 && power.Imaginary == 0) { return new Complex(1, 0); }
if (value.Real == 0 && value.Imaginary == 0) { return new Complex(0, 0); }
var a = value.Real;
var b = value.Imaginary;
var c = power.Real;
var d = power.Imaginary;
var rho = Complex.Abs(value);
var theta = (float)Math.Atan2(b, a);
var newRho = c * theta + d * Math.Log(rho);
var t = (float)Math.Pow(rho, c) * (float)Math.Pow(Math.E, -d * theta);
return new Complex(t * (float)Math.Cos(newRho), t * (float)Math.Sin(newRho));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment