The dragon curve looks like this:
The pattern by which you create it is very similar to the pattern used to created the Levy C curve. Instead of turning 'right' for every line segment, you alternate turning 'right' and left.' See the diagram below:
Adding some variation:
There's nothing that says the pattern we use has to be R L repeating, right? So let's try adding some variation to that pattern. In the following code, you can specify the pattern as a series of 1's and 0's to denote turning left and right, respectively. The pattern will repeat once it reaches the end.
Examples
Code
function Dragon_Curve(iterations,makeVideo,xlimVals,ylimVals,pattern)
% This function draws a Dragon Curve (or a variant of that curve) with the
% following inputs:
% iterations = int; number of iterations
% makeVideo = 1 or 0; set to 1 to make a video
% xlimVals = [xmin,xmax]; set the x-boundaries for the graph
% ylimVlas = [ymin,ymax]; set the y-boundaries for the graph
% pattern = pattern of 1's and 0's. For each 0, the pattern will turn
% right. For each 1 the pattern will turn left. When the pattern reaches
% the end, it will repeat. For example, [0,1] will generate the standard
% dragon curve
% If making a video, initialize the video object
if makeVideo==1
writerObj = VideoWriter('dragonCurveVideo.avi'); % Name it.
writerObj.FrameRate = 1;
writerObj.Quality=100;
open(writerObj)
end
angle=45;
pts=[-.5,0;.5,0];
len=1;
% Initialize the figure
figure('Position',[50,50,750,500],'Color',[1 1 1]);
c=[0 0 1];
% Draw the initial line
plot([-0.5 0.5],[0 0],'Color',c,'LineWidth',4)
hold on
xlim(xlimVals);
ylim(ylimVals);
axis off
% If making a video, grab a frame
if makeVideo==1
frame = getframe(1);
writeVideo(writerObj, frame)
pause(1)
end
% Repeat for the given number of iterations
for i=1:iterations
cla
len=0.5*len/cosd(angle);
temp=[];
dir=1;
% Repeast for each line segment in the curve
for j=1:size(pts,1)-1
% Grab the two endpoints of the curve
pt1=pts(j,:);
pt2=pts(j+1,:);
% Subtract one endpoint from the other so you're centered on
% zero and can more easily calculate the angle
pt2corr=pt2-pt1;
if 0>=pt2corr(1) && 0>=pt2corr(2)
theta=atand(abs(pt2corr(2)/pt2corr(1)))+180;
elseif 0>=pt2corr(1)
theta=180-atand(abs(pt2corr(2)/pt2corr(1)));
elseif 0>=pt2corr(2)
theta=360-atand(abs(pt2corr(2)/pt2corr(1)));
else
theta=atand(abs(pt2corr(2)/pt2corr(1)));
end
% Determine the new point (the 'midpoint') for your line segment
if pattern(dir)==0 % If turning RIGHT
midpt=[len*cosd(theta-angle)+pt1(1),len*sind(theta-angle)+pt1(2)];
else % If turning LEFT
midpt=[len*cosd(theta+angle)+pt1(1),len*sind(theta+angle)+pt1(2)];
end
% Determine the color based on the current iteration
c=[j/size(pts,1) 0 1-j/size(pts,1)];
% Plot the new line segments
plot([pt1(1),midpt(1),pt2(1)],[pt1(2),midpt(2),pt2(2)],'Color',c,'LineWidth',1)
hold on
xlim(xlimVals);
ylim(ylimVals);
axis off
% Add the new points to the temp variable
temp=[temp;pt1;midpt];
% Change direction based on the pattern
if dir==length(pattern)
dir=1;
else
dir=dir+1;
end
end
temp=[temp;pts(end,:)];
pts=temp;
% If making a video, grab a frame
if makeVideo==1
frame = getframe(1);
writeVideo(writerObj, frame)
end
pause(1)
end
% If making a video, grab a few frames of the final video and close the
% video object
if makeVideo==1
for i=1:5
frame = getframe(1);
writeVideo(writerObj, frame)
end
close(writerObj)
end
end
Using a square:
What if insted of starting with a line, we started with a square?
Examples
Note that, for this first one, I messed around with the coloring a bit.
Code
function Dragon_Curve_Square(iterations,makeVideo,xlimVals,ylimVals,pattern)
% This function draws a Dragon Curve (or a variant of that curve) with the
% following inputs:
% iterations = int; number of iterations
% makeVideo = 1 or 0; set to 1 to make a video
% xlimVals = [xmin,xmax]; set the x-boundaries for the graph
% ylimVlas = [ymin,ymax]; set the y-boundaries for the graph
% pattern = pattern of 1's and 0's. For each 0, the pattern will turn
% right. For each 1 the pattern will turn left. When the pattern reaches
% the end, it will repeat. For example, [0,1] will generate the standard
% dragon curve
% If making a video, initialize the video object
if makeVideo==1
writerObj = VideoWriter('dragonCurveVideo.avi'); % Name it.
writerObj.FrameRate = 1;
writerObj.Quality=100;
open(writerObj)
end
angle=45;
pts=[-.5,-.5;.5,-.5;.5,.5;-.5,.5;-.5,-.5];
len=1;
% Initialize the figure
figure('Position',[50,50,750,750],'Color',[1 1 1]);
c=[0 0 1];
% Draw the initial square
plot([-0.5 0.5 0.5 -0.5 -.5],[-.5 -.5 .5 .5 -.5],'Color',c,'LineWidth',1)
hold on
xlim(xlimVals);
ylim(ylimVals);
axis off
pause(2)
%dir=1;
% If making a video, grab a frame
if makeVideo==1
frame = getframe(1);
writeVideo(writerObj, frame)
end
% Repeat for the given number of iterations
for i=1:iterations
cla
len=0.5*len/cosd(angle);
temp=[];
dir=1;
% Repeast for each line segment in the curve
for j=1:size(pts,1)-1
% Grab the two endpoints of the curve
pt1=pts(j,:);
pt2=pts(j+1,:);
% Subtract one endpoint from the other so you're centered on
% zero and can more easily calculate the angle
pt2corr=pt2-pt1;
if 0>=pt2corr(1) && 0>=pt2corr(2)
theta=atand(abs(pt2corr(2)/pt2corr(1)))+180;
elseif 0>=pt2corr(1)
theta=180-atand(abs(pt2corr(2)/pt2corr(1)));
elseif 0>=pt2corr(2)
theta=360-atand(abs(pt2corr(2)/pt2corr(1)));
else
theta=atand(abs(pt2corr(2)/pt2corr(1)));
end
% Determine the new point (the 'midpoint') for your line segment
if pattern(dir)==0 % If turning RIGHT
midpt=[len*cosd(theta-angle)+pt1(1),len*sind(theta-angle)+pt1(2)];
else % If turning LEFT
midpt=[len*cosd(theta+angle)+pt1(1),len*sind(theta+angle)+pt1(2)];
end
% Determine the color based on the current iteration
c=[j/size(pts,1) 0 1-j/size(pts,1)];
% if j>(3/4)*size(pts,1)
% c=[.2,.9,.2];
% elseif j>(1/2)*size(pts,1)
% c=[0.1,0.6,0.1];
% elseif j>(1/4)*size(pts,1)
% c=[0,1,.5];
% else
% c=[.5,1,.5];
% end
% Plot the new line segments
plot([pt1(1),midpt(1),pt2(1)],[pt1(2),midpt(2),pt2(2)],'Color',c,'LineWidth',1)
hold on
xlim(xlimVals);
ylim(ylimVals);
axis off
% Add the new points to the temp variable
temp=[temp;pt1;midpt];
% Change direction based on the pattern
if dir==length(pattern)
dir=1;
else
dir=dir+1;
end
end
temp=[temp;pts(end,:)];
pts=temp;
% If making a video, grab a frame
if makeVideo==1
frame = getframe(1);
writeVideo(writerObj, frame)
end
pause(2)
end
% If making a video, grab a few frames of the final video and close the
% video object
if makeVideo==1
for i=1:5
frame = getframe(1);
writeVideo(writerObj, frame)
end
close(writerObj)
end
end