Fractal visualizer just got submitted.
This commit is contained in:
parent
93f4ba647f
commit
aafd3985d4
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ convimg.out
|
||||
# Other stuff.
|
||||
.DS_Store
|
||||
*/.vs/
|
||||
*.zip
|
||||
|
||||
Binary file not shown.
25
FractalVisualizer/FractalVisualizer.sln
Normal file
25
FractalVisualizer/FractalVisualizer.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.11.35327.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FractalVisualizer", "FractalVisualizer\FractalVisualizer.csproj", "{FE00D3E5-97BE-4DD3-92AB-8E0CEF64BAC2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FE00D3E5-97BE-4DD3-92AB-8E0CEF64BAC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FE00D3E5-97BE-4DD3-92AB-8E0CEF64BAC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FE00D3E5-97BE-4DD3-92AB-8E0CEF64BAC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FE00D3E5-97BE-4DD3-92AB-8E0CEF64BAC2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E98DD73D-4241-425D-B5CF-EC5B2B0D92EB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
18
FractalVisualizer/FractalVisualizer/Complex.cs
Normal file
18
FractalVisualizer/FractalVisualizer/Complex.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace FractalVisualizer;
|
||||
|
||||
public readonly struct Complex
|
||||
{
|
||||
public double MagSq => r * r + i * i;
|
||||
|
||||
public readonly double r, i;
|
||||
|
||||
public Complex(double r, double i)
|
||||
{
|
||||
this.r = r;
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
public static Complex operator +(Complex a, Complex b) => new(a.r + b.r, a.i + b.i);
|
||||
public static Complex operator -(Complex a, Complex b) => new(a.r - b.r, a.i - b.i);
|
||||
public static Complex operator *(Complex a, Complex b) => new(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r);
|
||||
}
|
||||
76
FractalVisualizer/FractalVisualizer/Forms/MainForm.Designer.cs
generated
Normal file
76
FractalVisualizer/FractalVisualizer/Forms/MainForm.Designer.cs
generated
Normal file
@ -0,0 +1,76 @@
|
||||
namespace FractalVisualizer.Forms
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
Viewer = new PictureBox();
|
||||
PositionLabel = new Label();
|
||||
((System.ComponentModel.ISupportInitialize)Viewer).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// Viewer
|
||||
//
|
||||
Viewer.Dock = DockStyle.Fill;
|
||||
Viewer.Location = new Point(0, 0);
|
||||
Viewer.Name = "Viewer";
|
||||
Viewer.Size = new Size(1366, 822);
|
||||
Viewer.TabIndex = 0;
|
||||
Viewer.TabStop = false;
|
||||
//
|
||||
// PositionLabel
|
||||
//
|
||||
PositionLabel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
PositionLabel.AutoSize = true;
|
||||
PositionLabel.Font = new Font("Segoe UI", 16.125F, FontStyle.Bold, GraphicsUnit.Point, 0);
|
||||
PositionLabel.Location = new Point(12, 754);
|
||||
PositionLabel.Name = "PositionLabel";
|
||||
PositionLabel.Size = new Size(295, 59);
|
||||
PositionLabel.TabIndex = 1;
|
||||
PositionLabel.Text = "PositionLabel";
|
||||
PositionLabel.TextAlign = ContentAlignment.BottomLeft;
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(13F, 32F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1366, 822);
|
||||
Controls.Add(PositionLabel);
|
||||
Controls.Add(Viewer);
|
||||
Name = "MainForm";
|
||||
Text = "MainForm";
|
||||
((System.ComponentModel.ISupportInitialize)Viewer).EndInit();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private PictureBox Viewer;
|
||||
private Label PositionLabel;
|
||||
}
|
||||
}
|
||||
205
FractalVisualizer/FractalVisualizer/Forms/MainForm.cs
Normal file
205
FractalVisualizer/FractalVisualizer/Forms/MainForm.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using Nerd_STF.Mathematics;
|
||||
|
||||
namespace FractalVisualizer.Forms
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public Float2 ScreenCenter { get; set; }
|
||||
public Float2 Dpi { get; private set; }
|
||||
public Float2 ZoomLevel { get; set; }
|
||||
|
||||
public Action<Complex> FuncSetup { get; set; }
|
||||
public Func<Complex, Complex> Func { get; set; }
|
||||
public int MaxIterations { get; set; }
|
||||
public double CutoffMagnitude { get; set; }
|
||||
public bool OptimizeIterations { get; set; }
|
||||
|
||||
public MainForm(Action<Complex> setup, Func<Complex, Complex> func)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
SetStyle(ControlStyles.UserPaint, true);
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
|
||||
Graphics tempG = CreateGraphics();
|
||||
Dpi = (tempG.DpiX, tempG.DpiY);
|
||||
tempG.Dispose();
|
||||
|
||||
ZoomLevel = Float2.One;
|
||||
FuncSetup = setup;
|
||||
Func = func;
|
||||
|
||||
Viewer.MouseDown += (o, e) => OnMouseDown(e);
|
||||
Viewer.MouseMove += (o, e) => OnMouseMove(e);
|
||||
Viewer.MouseUp += (o, e) => OnMouseUp(e);
|
||||
|
||||
UpdatePositionText();
|
||||
BeginRender();
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
BeginRender();
|
||||
}
|
||||
|
||||
public void BeginRender()
|
||||
{
|
||||
if (renderTask is not null)
|
||||
{
|
||||
renderCancel!.Cancel();
|
||||
renderTask.Wait();
|
||||
|
||||
renderCancel.Dispose();
|
||||
renderTask.Dispose();
|
||||
}
|
||||
renderCancel = new CancellationTokenSource();
|
||||
renderTask = Task.Run(async () => await Render(8, true, renderCancel.Token));
|
||||
}
|
||||
|
||||
private static Color ColorFromIters(int i, int max)
|
||||
{
|
||||
if (i == 0 || i == max) return Color.Black;
|
||||
|
||||
int brightestR = 33,
|
||||
brightestG = 204,
|
||||
brightestB = 38;
|
||||
|
||||
double intensity = 1 - 1.0 / i;
|
||||
int r = (int)(brightestR * intensity),
|
||||
g = (int)(brightestG * intensity),
|
||||
b = (int)(brightestB * intensity);
|
||||
return Color.FromArgb(g, r, b);
|
||||
}
|
||||
|
||||
private CancellationTokenSource? renderCancel;
|
||||
private Task? renderTask;
|
||||
private Task Render(int depth, bool recurse, CancellationToken token)
|
||||
{
|
||||
DateTime start = DateTime.Now;
|
||||
Graphics g = Viewer.CreateGraphics();
|
||||
SolidBrush pen = new(Color.Black);
|
||||
double cutoff = CutoffMagnitude * CutoffMagnitude;
|
||||
int maxIters = MaxIterations;
|
||||
if (OptimizeIterations) maxIters /= depth + 1;
|
||||
|
||||
int step = 1 << depth;
|
||||
for (int x = 0; x < Viewer.Width; x += step)
|
||||
{
|
||||
for (int y = 0; y < Viewer.Height; y += step)
|
||||
{
|
||||
if (token.IsCancellationRequested) return Task.CompletedTask;
|
||||
|
||||
Int2 point = (x, y);
|
||||
Float2 coords = ScreenSpaceToGraphSpace(point);
|
||||
Complex num = new(coords.x, coords.y);
|
||||
FuncSetup(num);
|
||||
int i;
|
||||
for (i = 0; i < maxIters; i++)
|
||||
{
|
||||
if (token.IsCancellationRequested) return Task.CompletedTask;
|
||||
num = Func(num);
|
||||
if (num.MagSq >= CutoffMagnitude) break;
|
||||
}
|
||||
|
||||
if (token.IsCancellationRequested) return Task.CompletedTask;
|
||||
pen.Color = ColorFromIters(i, maxIters);
|
||||
g.FillRectangle(pen, new Rectangle(x, y, step, step));
|
||||
}
|
||||
}
|
||||
|
||||
g.Dispose();
|
||||
pen.Dispose();
|
||||
if (recurse && depth > 0) return Render(depth - 1, true, token);
|
||||
else return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Int2 GraphSpaceToScreenSpace(Float2 graphPoint)
|
||||
{
|
||||
graphPoint.y = -graphPoint.y;
|
||||
|
||||
graphPoint.x -= ScreenCenter.x;
|
||||
graphPoint.y -= ScreenCenter.y;
|
||||
|
||||
graphPoint.x *= Dpi.x / ZoomLevel.x;
|
||||
graphPoint.y *= Dpi.y / ZoomLevel.y;
|
||||
|
||||
graphPoint.x += Viewer.Width / 2.0;
|
||||
graphPoint.y += Viewer.Height / 2.0;
|
||||
|
||||
return new((int)graphPoint.x, (int)graphPoint.y);
|
||||
}
|
||||
public Float2 ScreenSpaceToGraphSpace(Int2 screenPoint)
|
||||
{
|
||||
Float2 result = new(screenPoint.x, screenPoint.y);
|
||||
|
||||
result.x -= Viewer.Width / 2.0;
|
||||
result.y -= Viewer.Height / 2.0;
|
||||
|
||||
result.x /= Dpi.x / ZoomLevel.x;
|
||||
result.y /= Dpi.y / ZoomLevel.y;
|
||||
|
||||
result.x += ScreenCenter.x;
|
||||
result.y += ScreenCenter.y;
|
||||
|
||||
result.y = -result.y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void UpdatePositionText()
|
||||
{
|
||||
PositionLabel.Text = $"{ScreenCenter.ToString("0.000")} - {100.0 * ZoomLevel.x:0.000000}%";
|
||||
PositionLabel.Invalidate();
|
||||
}
|
||||
|
||||
private bool dragging;
|
||||
private Int2 initialDragPoint;
|
||||
private Float2 initialCenter;
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
if (!dragging)
|
||||
{
|
||||
initialCenter = ScreenCenter;
|
||||
initialDragPoint = new Int2(Cursor.Position.X, Cursor.Position.Y);
|
||||
dragging = true;
|
||||
}
|
||||
}
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
Int2 pixelDiff = new(initialDragPoint.x - Cursor.Position.X,
|
||||
initialDragPoint.y - Cursor.Position.Y);
|
||||
Float2 graphDiff = new(pixelDiff.x * ZoomLevel.x / Dpi.x, pixelDiff.y * ZoomLevel.y / Dpi.y);
|
||||
ScreenCenter = new(initialCenter.x + graphDiff.x,
|
||||
initialCenter.y + graphDiff.y);
|
||||
BeginRender();
|
||||
dragging = false;
|
||||
}
|
||||
}
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
Int2 pixelDiff = new(initialDragPoint.x - Cursor.Position.X,
|
||||
initialDragPoint.y - Cursor.Position.Y);
|
||||
Float2 graphDiff = new(pixelDiff.x * ZoomLevel.x / Dpi.x, pixelDiff.y * ZoomLevel.y / Dpi.y);
|
||||
ScreenCenter = new(initialCenter.x + graphDiff.x,
|
||||
initialCenter.y + graphDiff.y);
|
||||
UpdatePositionText();
|
||||
BeginRender();
|
||||
}
|
||||
}
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
Float2 newZoom = ZoomLevel;
|
||||
newZoom.x *= 1 - e.Delta * 0.00075; // Zoom factor.
|
||||
newZoom.y *= 1 - e.Delta * 0.00075;
|
||||
ZoomLevel = newZoom;
|
||||
UpdatePositionText();
|
||||
BeginRender();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
FractalVisualizer/FractalVisualizer/Forms/MainForm.resx
Normal file
120
FractalVisualizer/FractalVisualizer/Forms/MainForm.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
15
FractalVisualizer/FractalVisualizer/FractalVisualizer.csproj
Normal file
15
FractalVisualizer/FractalVisualizer/FractalVisualizer.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nerd_STF" Version="3.0.0-beta1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Compile Update="Forms\MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
31
FractalVisualizer/FractalVisualizer/Program.cs
Normal file
31
FractalVisualizer/FractalVisualizer/Program.cs
Normal file
@ -0,0 +1,31 @@
|
||||
/**********722871**********
|
||||
* Date: 11/13/2024
|
||||
* Programmer: Kyle Gilbert
|
||||
* Program Name: Fractal Visualizer
|
||||
* Program Description: A visualizer for complex-based iterative fractals.
|
||||
**************************/
|
||||
|
||||
using FractalVisualizer.Forms;
|
||||
|
||||
namespace FractalVisualizer;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
|
||||
Application.Run(new MainForm(MandlebrotSetup, MandlebrotIter)
|
||||
{
|
||||
MaxIterations = 512,
|
||||
CutoffMagnitude = 4,
|
||||
});
|
||||
}
|
||||
|
||||
private static Complex start;
|
||||
private static void MandlebrotSetup(Complex num) => start = num;
|
||||
private static Complex MandlebrotIter(Complex num) => num * num + start;
|
||||
}
|
||||
@ -36,3 +36,8 @@ I have about 1-2 weeks for each project. Check the Git commits for specific date
|
||||
- Create a `.sce` file (a somewhat easy to use plain text format)
|
||||
- Nice colors for each object. Scales seamlessly with a higher DPI.
|
||||
- Sweeps possible angles and speeds to try and find the path that brings the ball closest to the end point.
|
||||
- Fractal Visualizer
|
||||
- A program that can be used to visualize fractals.
|
||||
- Allows you to zoom in and drag the screen around in real time.
|
||||
- Renders in multiple resolution scales so as to be as responsive as possible. Upscales over time.
|
||||
- Currently does the mandlebrot set. It has support for any complex iterative fractal, but you have to code it yourself.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user