Skip to content

Commit

Permalink
Project Upload
Browse files Browse the repository at this point in the history
  • Loading branch information
DacodaDragon committed Aug 18, 2019
1 parent 8517cb9 commit a4d075e
Show file tree
Hide file tree
Showing 15 changed files with 566 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/MandelBrot.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.539
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MandelBrot", "MandelBrot\MandelBrot.csproj", "{64087C44-EACD-4E80-AA68-70E30AF717E5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{64087C44-EACD-4E80-AA68-70E30AF717E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64087C44-EACD-4E80-AA68-70E30AF717E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64087C44-EACD-4E80-AA68-70E30AF717E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64087C44-EACD-4E80-AA68-70E30AF717E5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A584772F-1983-40C4-93EE-D7ECFE2CC7F0}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions src/MandelBrot/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
70 changes: 70 additions & 0 deletions src/MandelBrot/Array2D.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Text;

namespace MandelbrotRenderer
{
/// <summary>
/// Wrapper around a 2D array with some utility functions I found handy
/// </summary>
/// <typeparam name="T"></typeparam>
class Array2D<T>
{
private T[][] _Array;

public int Width { get; }
public int Height { get; }
public int TotalSize => Width * Height;

public Array2D(int width, int height)
{
Width = width;
Height = height;

_Array = new T[width][];

for (int i = 0; i < width; i++)
_Array[i] = new T[height];
}

public void Each(Func<int, int, T> _Callback)
{
for (int x = 0; x < Width; x++)
for (int y = 0; y < Height; y++)
_Array[x][y] = _Callback(x, y);
}

public void Each(Action<int, int> _Callback)
{
for (int x = 0; x < Width; x++)
for (int y = 0; y < Height; y++)
_Callback(x, y);
}

public void Each(Action<T> _Callback)
{
for (int x = 0; x < Width; x++)
for (int y = 0; y < Height; y++)
_Callback(_Array[x][y]);
}

public T this[int x, int y]
{
get { return _Array[x][y]; }
set { _Array[x][y] = value; }
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
sb.Append(this[x, y].ToString()).Append(", ");
}
sb.Append('\n');
}
return sb.ToString();
}
}
}
65 changes: 65 additions & 0 deletions src/MandelBrot/ColorCurve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Drawing;
using System;
using System.Collections.Generic;

namespace MandelbrotRenderer
{
/// <summary>
/// Quick and dirty implementation of a curve in color space
/// </summary>
class ColorCurve
{
private Curve _R, _G, _B;

public ColorCurve(Curve r, Curve g, Curve b)
{
this._R = r;
this._G = g;
this._B = b;
}

public Color Sample(double value)
{
int r = (int)Math.Min(_R.Sample(value) * 255, 255);
int g = (int)Math.Min(_G.Sample(value) * 255, 255);
int b = (int)Math.Min(_B.Sample(value) * 255, 255);
return Color.FromArgb(r, g, b);
}

public static ColorCurve Parse(string args)
{
string[] values = args.Split(' ');

List<Keyframe> redCurve = new List<Keyframe>();
List<Keyframe> greenCurve = new List<Keyframe>();
List<Keyframe> blueCurve = new List<Keyframe>();

for (int j = 0; j < values.Length; j++)
{
switch (values[j].ToLower())
{
case "r":
while (j + 2 < values.Length && double.TryParse(values[++j], out double pos) && double.TryParse(values[++j], out double val))
redCurve.Add(new Keyframe(pos, val));
--j;
break;
case "g":
while (j + 2 < values.Length && double.TryParse(values[++j], out double pos) && double.TryParse(values[++j], out double val))
greenCurve.Add(new Keyframe(pos, val));
--j;
break;
case "b":
while (j + 2 < values.Length && double.TryParse(values[++j], out double pos) && double.TryParse(values[++j], out double val))
blueCurve.Add(new Keyframe(pos, val));
--j;
break;
}
}

return new ColorCurve(
new Curve(redCurve.ToArray()),
new Curve(greenCurve.ToArray()),
new Curve(blueCurve.ToArray()));
}
}
}
29 changes: 29 additions & 0 deletions src/MandelBrot/ComplexNumber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace MandelbrotRenderer
{
/// <summary>
/// Represents a complex number
/// </summary>
struct ComplexNumber
{
public double re; // real part of complex number
public double im; // imaginary part of complex number "x*Sqrt(-1))"

public ComplexNumber(double x, double y)
{
this.re = x;
this.im = y;
}

public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b)
=> new ComplexNumber(a.re + b.re, a.im + b.im);

public static ComplexNumber operator *(ComplexNumber a, ComplexNumber b)
=> new ComplexNumber(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re);

public double Norm
=> re * re + im * im;

public static ComplexNumber Zero
=> new ComplexNumber();
}
}
27 changes: 27 additions & 0 deletions src/MandelBrot/Curve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace MandelbrotRenderer
{
/// <summary>
/// Quick and dirty implementation of a keyframed curve where values in between keyframes are interpolated linearly
/// </summary>
class Curve
{
Keyframe[] _Keyframes;

public Curve(params Keyframe[] keyframes)
{
_Keyframes = keyframes;
}

public double Sample(double value)
{
for (int i = 1; i < _Keyframes.Length; i++)
if (value < _Keyframes[i].position)
return MathExtension.MapRange(value,
_Keyframes[i - 1].position,
_Keyframes[i].position,
_Keyframes[i - 1].value,
_Keyframes[i].value);
return 1;
}
}
}
17 changes: 17 additions & 0 deletions src/MandelBrot/Keyframe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace MandelbrotRenderer
{
/// <summary>
/// Quick and dirty implementation of a keyframe for in curves
/// </summary>
struct Keyframe
{
public double position;
public double value;

public Keyframe(double position, double value)
{
this.position = position;
this.value = value;
}
}
}
52 changes: 52 additions & 0 deletions src/MandelBrot/MandelBrot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

using System.Diagnostics;

namespace MandelbrotRenderer
{
/// <summary>
/// Contains the mandelbrot formula and a utility function to fill a 2D array with values from a section of the mandelbrot.
/// </summary>
static class MandelBrot
{
const double MAX_VALUE_EXTENT = 2.0;
const double MAX_NORM = MAX_VALUE_EXTENT * MAX_VALUE_EXTENT;

public static double Calculate(ComplexNumber c)
{
int maxIterations = Settings.Global.Iterations;

ComplexNumber z = ComplexNumber.Zero;
int i = 0;

do { z = z * z + c; ++i; }
while (z.Norm < MAX_NORM && i < maxIterations);

if (i < maxIterations)
return (double)i / maxIterations;

return 0;
}

public static Array2D<double> GetValues(Rect rect, int pixelWidth, int pixelHeight)
{
Array2D<double> array2D = new Array2D<double>(pixelWidth, pixelHeight);
Stopwatch stopwatch = Stopwatch.StartNew();
Stopwatch timer = Stopwatch.StartNew();

array2D.Each((x, y) =>
{
if (stopwatch.ElapsedMilliseconds > 40)
{
int percentage = (int)(((x *array2D.Height) + y) / (double)array2D.TotalSize * 100);
System.Console.Write($"\rCalculating Mandelbrot: {percentage}% x:{x} y:{y}");
stopwatch.Restart();
}
return Calculate(new ComplexNumber(rect.MapWidth(x, 0, pixelWidth), rect.MapHeight(y, 0, pixelHeight)));
});

System.Console.WriteLine($"\rCalculating Mandelbrot: 100% x:{array2D.Width} y:{array2D.Height}");
System.Console.WriteLine($"Calculations done: {timer.Elapsed}");
return array2D;
}
}
}
64 changes: 64 additions & 0 deletions src/MandelBrot/MandelBrot.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{64087C44-EACD-4E80-AA68-70E30AF717E5}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>MandelBrot</RootNamespace>
<AssemblyName>MandelBrot</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Array2D.cs" />
<Compile Include="ColorCurve.cs" />
<Compile Include="ComplexNumber.cs" />
<Compile Include="Curve.cs" />
<Compile Include="Keyframe.cs" />
<Compile Include="MandelBrot.cs" />
<Compile Include="MathExtension.cs" />
<Compile Include="Program.cs" />
<Compile Include="ProgramOptions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Rect.cs" />
<Compile Include="ValueSpectrumRenderer.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
13 changes: 13 additions & 0 deletions src/MandelBrot/MathExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace MandelbrotRenderer
{
/// <summary>
/// Container for globally used math
/// </summary>
class MathExtension
{
public static double MapRange(double s, double a1, double a2, double b1, double b2)
{
return b1 + (s - a1) * (b2 - b1) / (a2 - a1);
}
}
}
Loading

0 comments on commit a4d075e

Please sign in to comment.