## The Dragon

I’ve been looking at the Dragon fractal, and wrote my own algorithm for it. Most of the examples online require a purely horizontal or vertical solution. I have generalized it to allow for a starting point/ending point for the initial line segment. I could probably allow rotational direction to be parameterized as well – but hey, I have real work to do. The code is fairly simple. It is written in C#, using WPF, though much of the logic could  easily be abstracted into another language or windowed framework. It pretty much takes a count of iterations to produce the sequence of right/left turns. The original points determine the line-segment length. I’ve customized the display logic so that the curve remains within the boundaries of the canvas (and scrollable).

UPDATE: Here is a nicer image, done with more iterations and a smaller segment length… The contents of Window1.xaml.cs:

```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace DragonFractal
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public enum Direction { Right, Left };
public class ColoredDirection
{
public Direction Turn = Direction.Right;

{
Turn = turn;
}
public ColoredDirection(Direction turnRight)
{
Turn = turnRight;
}
public ColoredDirection()
{
}
}

public Window1()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
SolidColorBrush brush = Brushes.DarkOliveGreen;

Clear();

List<ColoredDirection> list = new List<ColoredDirection>();
for (int i = 0; i < int.Parse(Iterations.Text); i++)
{
List<ColoredDirection> nextList = new List<ColoredDirection>(list);

list.Reverse();

foreach (ColoredDirection direction in list)
{
ColoredDirection newDirection = new ColoredDirection();
if (direction.Turn == Direction.Right)
{
newDirection.Turn = Direction.Left;
}
else
{
newDirection.Turn = Direction.Right;
}

}
list = nextList;

Color color = new Color();
color.R = brush.Color.B;
color.B = brush.Color.G;
color.G = brush.Color.R;
color.A = brush.Color.A;
brush = new SolidColorBrush(color);
}
ColoredDirection[] directions = list.ToArray();

double x1 = double.Parse(X1.Text);
minX = x1;
maxX = x1;
double y1 = double.Parse(Y1.Text);
minY = y1;
maxY = y1;
double x2 = double.Parse(X2.Text);
double y2 = double.Parse(Y2.Text);

double segmentLength = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));

DrawLine(Brushes.Black, x1, y1, x2, y2);

for (int segment = 0; segment < directions.Length; segment++)
{
double lastAngleX = Math.Acos(Math.Round(x2 - x1,5) / segmentLength);
double lastAngleY = Math.Asin(Math.Round(y2 - y1,5) / segmentLength);

double currentAngle = (Math.Sign(lastAngleY) == -1.0) ? (360.0 * Math.PI / 180.0 - lastAngleX) : (lastAngleX);
currentAngle = currentAngle + ((directions[segment].Turn==Direction.Left) ? 90 : -90) * Math.PI / 180.0;

x1 = x2;
y1 = y2;
x2 = x1 + segmentLength * Math.Cos(currentAngle);
y2 = y1 + segmentLength * Math.Sin(currentAngle);

Line line = DrawLine(directions[segment].Shade, x1, y1, x2, y2);
}

}

private Line DrawLine(SolidColorBrush brush,double x1, double y1, double x2, double y2)
{
Line myLine = new Line();
myLine.Stroke = brush;
myLine.X1 = x1;
myLine.X2 = x2;
myLine.Y1 = y1;
myLine.Y2 = y2;
myLine.StrokeThickness = 1;
myLine.RenderTransformOrigin = new Point(0, 0);
myLine.RenderTransform = Translator;

ManageDrawingArea(x2, y2);

return myLine;
}

private void Clear()
{
canvas1.Children.Clear();

minX = 0.0;
minY = 0.0;
maxX = 0.0;
maxY = 0.0;

Translator.X = 0;
Translator.Y = 0;
}

TranslateTransform Translator = new TranslateTransform(0, 0);
double minX = 0.0;
double minY = 0.0;
double maxX = 0.0;
double maxY = 0.0;
private void ManageDrawingArea(double x2, double y2)
{
if (x2 < minX) minX = x2;
if (x2 > maxX) maxX = x2;
if (y2 < minY) minY = y2;
if (y2 > maxY) maxY = y2;

if (minX < 0)
{
Translator.X = -minX + 10.0;
canvas1.Width = maxX - minX + 10.0;
}
else
{
canvas1.Width = maxX;
}

if (minY < 0)
{
Translator.Y = -minY + 10.0;
canvas1.Height = maxY - minY + 10.0;
}
else
{
canvas1.Height = maxY;
}
}
}
}```

The contents of Window1.xaml:

```<Window x:Class="DragonFractal.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Height="23" Margin="10.829,0,0,76.636" Name="button1" VerticalAlignment="Bottom" Click="button1_Click" HorizontalAlignment="Left" Width="75.581">Run</Button>
<TextBox Height="23" Margin="19.159,0,138.278,45.815" Name="X1" VerticalAlignment="Bottom">40</TextBox>
<TextBox Height="23" HorizontalAlignment="Right" Margin="0,0,6.664,45.815" Name="Y1" VerticalAlignment="Bottom" Width="120">40</TextBox>
<TextBox Height="23" Margin="19.159,0,138.278,17.493" Name="X2" VerticalAlignment="Bottom">50</TextBox>
<TextBox Height="23" HorizontalAlignment="Right" Margin="0,0,6.664,17.493" Name="Y2" VerticalAlignment="Bottom" Width="120">50</TextBox>
<TextBox Height="23" Margin="94.962,0,107.457,74.774" Name="Iterations" VerticalAlignment="Bottom">1</TextBox>
<ScrollViewer Name="scrollViewer1" Margin="0,0,0,101.626" CanContentScroll="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Canvas Name="canvas1" ClipToBounds="False" Background="AntiqueWhite" HorizontalAlignment="Left" VerticalAlignment="Top" Height="158.27" Width="260.729"></Canvas>
</ScrollViewer>
</Grid>
</Window>``` I'm interested in theology, languages, translation and various sorts of fermentation.
This entry was posted in Code Samples, Mathematics and tagged , , . Bookmark the permalink.

### 2 Responses to The Dragon

1. George says:

Just to be clear – the code is setup for “Right” rotation, as compared to “Left”. However, The coordinate system in WPF sets (0,0) at the upper left hand corner, which means the representation on screen is upside down… giving the impression of “Left” rotation. I could probably skew the whole thing with a Transform in such a way as to reverse the effect, but did not do so.

2. George says:

Ok, went ahead and figured it out – how to flip the coordinate system (so to speak). It at least gets rotation in the expected direction.

Hust add the following code in the Clear() method.

canvas1.RenderTransformOrigin = new Point(0.5, 0.5);
canvas1.RenderTransform = new ScaleTransform(1, -1);