# Hilbert Curve

One of my favourite topics in math is fractals. For this post, I drew the Hilbert Curve fractal in octave.

The Hilbert Curve is a space-filling curve: although it is one-dimensional (a series of line segments) itself, it covers a two-dimensional area. I recently learned about this fractal from a post on Andrea Hawksley's blog.

(Her blog also has some other math art and some ideas for playing chess and Carcassonne on non-Euclidean boards (i.e. not on flat grids)).

To draw the Hilbert Curve, I wrote a script in octave to implement the Lindenmayer system algorithm from Wikipedia. The results are shown below, after 5 and 7 iterations, respectively. The script I wrote is included at the end of this post.

With its space-filling properties, the Hilbert Curve has some commonalities with tiling, another mathematical topic that really interests me. I really like the aesthetics of this fractal.

### Images  ### Octave Code

``````%% Hilbert.m - this is a script to draw the space-filling Hilbert curve.
% From Wikipedia, the algorithm is as follows:
% A = - B F + A F A + F B -
% B = + A F - B F B - F A +
% Where: F indicates move forward, - is a left turn (which actually should
%  be positive, using the right hand rule), + is a right turn, and A and B
%  are place-holders that are expanded as indicated above on each iteration.
% (In the script below, numbers 1 - 5 are used for A, B, -, +, and F,
%  respectively)
% This script has 3 parts: 1. generate the instruction list to the depth
%  (number of iterations) desired. 2. calculate the coordinates of each
%  vertex on the curve. 3. plot the curve.

%% Generate the instruction list

A = [ 3 2 5 4 1 5 1 4 5 2 3 ];
B = [ 4 1 5 3 2 5 2 3 5 1 4 ];
Depth = input("How many iterations? \n");
InstList = A;
Iter = 1;

while Iter < Depth
for Item = 1:length(InstList)
switch (InstList(Item))
case 1
InstListNew = [ InstListNew, A ]; %expand the instruction list where appropriate
case 2
InstListNew = [ InstListNew, B ];
otherwise
InstListNew = [ InstListNew, InstList(Item) ];
endswitch
end
InstList = InstListNew;
Iter = Iter + 1;
end

%% Calculate the vertex coordinates

R3 = [ 0 -1; 1 0 ]; %rotation matrix for left turn ("3" in instruction list)
R4 = [ 0 1; -1 0 ]; %rotation matrix for right turn ("4" in instruction list)
dir = [ 1; 0 ]; %initial direction vector points along the x-axis
posx = 0; %initial position is (0,0)
posy = 0;

xpts = [ posx ]; %initialize x and y vectors, plus distance tally and a step counter
ypts = [ posy ];
distance = [ 0 ];
step = 1;

for Index = 1:length(InstList)
switch (InstList(Index))
case 3
dir = R3*dir; %rotate left
case 4
dir = R4*dir; %rotate right
case 5
posx = posx + dir(1); %move forward in the direction currently faced.
posy = posy + dir(2);
step = step + 1;
xpts(step) = posx; %record current position
ypts(step) = posy;
distance(step) = (step - 1); %record cumulative distance travelled
endswitch
end

%% Draw the curve
plot(xpts,ypts,'b-'); %plot the recorded points
xlim([-1, (max(xpts)+1)]);
ylim([-1, (max(ypts)+1)]);

%It might also be of interest to plot x and/or y vs the distance travelled
% (commented out for now)
%plot(distance,xpts,'g-');
%plot(distance,ypts,'r-');

%Note: save the figure using the command 'print('filename.png','-dpng')'
``````