Dragon curve: Difference between revisions

71,833 bytes added ,  2 months ago
m
Algol 68 →‎L-System: comments
m (Algol 68 →‎L-System: comments)
 
(95 intermediate revisions by 33 users not shown)
Line 102:
 
The string rewrites can be done recursively without building the whole string, just follow its instructions at the target level. See for example [[#C by IFS Drawing|C by IFS Drawing]] code. The effect is the same as "recursive with parameter" above but can draw other curves defined by L-systems. <br><br>
 
=={{header|Ada}}==
This example uses GTKAda and Cairo.
 
<div>[[File:Dragoncurve ada cairo.png|thumb]]</div>
 
<syntaxhighlight lang="Ada">
-- FILE: dragon_curve.gpr --
with "gtkada";
 
project Dragon_Curve is
Adaflags := External_As_List ("ADAFLAGS", " ");
Ldflags := External_As_List ("LDFLAGS", " ");
 
for Languages use ("Ada");
for Main use ("dragon_curve.adb");
for Source_Dirs use ("./");
for Object_Dir use "obj/";
for Exec_Dir use ".";
 
package Compiler is
for Switches ("Ada") use ("-g", "-O0", "-gnaty-s", "-gnatwJ")
& Adaflags;
end Compiler;
 
package Linker is
for Leading_Switches ("Ada") use Ldflags;
end Linker;
 
end Dragon_Curve;
</syntaxhighlight>
 
<syntaxhighlight lang="Ada">
-- FILE: dragon_curve.adb --
with Ada.Text_IO; use Ada.Text_IO;
with Events; use Events;
with GLib.Main; use GLib.Main;
with GTK;
with GTK.Drawing_Area; use GTK.Drawing_Area;
with GTK.Main;
with GTK.Window; use GTK.Window;
 
procedure Dragon_Curve is
Window : GTK_Window;
begin
GTK.Main.Init;
GTK_New (Window);
GTK_New (Drawing_Area);
Window.Add (Drawing_Area);
Drawing_Area.On_Draw (Events.Draw'Access, Drawing_Area);
Show_All (Window);
Resize (Window, 800, 800);
GTK.Main.Main;
end Dragon_Curve;
</syntaxhighlight>
 
<syntaxhighlight lang="Ada">
-- FILE: events.ads --
with Ada.Numerics.Generic_Elementary_Functions;
with Cairo;
with GLib; use Glib;
with GTK.Drawing_Area; use GTK.Drawing_Area;
with GTK.Widget; use GTK.Widget;
with GLib.Object; use GLib.Object;
 
package Events is
Drawing_Area : GTK_Drawing_Area;
 
package GDouble_Elementary_Functions is new Ada.Numerics.Generic_Elementary_Functions (Float);
use GDouble_Elementary_Functions;
 
function Draw (Self : access GObject_Record'Class;
CC : Cairo.Cairo_Context)
return Boolean;
end Events;
</syntaxhighlight>
 
<syntaxhighlight lang="Ada">
-- FILE: events.adb --
with Cairo;
with GTK;
 
package body Events is
function Draw (Self : access GObject_Record'Class;
CC : Cairo.Cairo_Context)
return Boolean
is
type Rotate_Type is (Counterclockwise, Clockwise);
 
type Point is record
X, Y : GDouble;
end record;
procedure Heighway_Branch (CC : Cairo.Cairo_Context;
A, B : Point;
Rotate : Rotate_Type;
N : Natural)
is
R, RU, C : Point;
begin
if N = 0 then
Cairo.Move_To (CC, A.X, A.Y);
Cairo.Line_To (CC, B.X, B.Y);
Cairo.Stroke (CC);
else
-- Rotate 45 degrees --
case Rotate is
when Clockwise =>
R.X := GDouble ((1.0 / Sqrt (2.0)) * Float (B.X - A.X)
- (1.0 / Sqrt (2.0)) * Float (B.Y - A.Y));
R.Y := GDouble ((1.0 / Sqrt (2.0)) * Float (B.X - A.X)
+ (1.0 / Sqrt (2.0)) * Float (B.Y - A.Y));
when Counterclockwise =>
R.X := GDouble ((1.0 / Sqrt (2.0)) * Float (B.X - A.X)
+ (1.0 / Sqrt (2.0)) * Float (B.Y - A.Y));
R.Y := GDouble (-(1.0 / Sqrt (2.0)) * Float (B.X - A.X)
+ (1.0 / Sqrt (2.0)) * Float (B.Y - A.Y));
end case;
 
-- Make unit vector from rotation --
RU.X := GDouble (Float (R.X) / Sqrt ( Float (R.X ** 2 + R.Y ** 2)));
RU.Y := GDouble (Float (R.Y) / Sqrt ( Float (R.X ** 2 + R.Y ** 2)));
 
-- Scale --
R.X := RU.X * GDouble (Sqrt (Float (B.X - A.X) ** 2 + Float (B.Y - A.Y) ** 2) / Sqrt (2.0));
R.Y := RU.Y * GDouble (Sqrt (Float (B.X - A.X) ** 2 + Float (B.Y - A.Y) ** 2) / Sqrt (2.0));
 
C := (R.X + A.X, R.Y + A.Y);
Heighway_Branch (CC, A, C, Clockwise, N - 1);
Heighway_Branch (CC, C, B, Counterclockwise, N - 1);
end if;
end Heighway_Branch;
 
Depth : constant := 14;
Center, Right, Bottom, Left: Point;
Width : GDouble := GDouble (Drawing_Area.Get_Allocated_Width);
Height : GDouble := GDouble (Drawing_Area.Get_Allocated_Height);
 
begin
Center := (Width / 2.0, Height / 2.0);
Right := (Width, Height / 2.0);
Left := (0.0, Height / 2.0);
Bottom := (Width / 2.0, Height);
 
Cairo.Set_Source_RGB (CC, 0.0, 1.0, 0.0);
Heighway_Branch (CC, Center, Right, Clockwise, Depth);
Cairo.Set_Source_RGB (CC, 0.0, 1.0, 1.0);
Heighway_Branch (CC, Center, Left, Clockwise, Depth);
Cairo.Set_Source_RGB (CC, 0.0, 1.0, 0.5);
Heighway_Branch (CC, Center, Bottom, Clockwise, Depth);
return True;
end Draw;
end Events;
</syntaxhighlight>
 
=={{header|Action!}}==
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed.
<syntaxhighlight lang="action!">DEFINE MAXSIZE="20"
 
INT ARRAY
xStack(MAXSIZE),yStack(MAXSIZE),
dxStack(MAXSIZE),dyStack(MAXSIZE)
BYTE ARRAY
dirStack(MAXSIZE),
depthStack(MAXSIZE),stageStack(MAXSIZE)
BYTE stacksize=[0]
 
BYTE FUNC IsEmpty()
IF stacksize=0 THEN RETURN (1) FI
RETURN (0)
 
BYTE FUNC IsFull()
IF stacksize=MAXSIZE THEN RETURN (1) FI
RETURN (0)
 
PROC Push(INT x,y,dx,dy BYTE dir,depth,stage)
IF IsFull() THEN Break() FI
xStack(stacksize)=x yStack(stacksize)=y
dxStack(stacksize)=dx dyStack(stacksize)=dy
dirStack(stacksize)=dir
depthStack(stacksize)=depth
stageStack(stackSize)=stage
stacksize==+1
RETURN
 
PROC Pop(INT POINTER x,y,dx,dy BYTE POINTER dir,depth,stage)
IF IsEmpty() THEN Break() FI
stacksize==-1
x^=xStack(stacksize) y^=yStack(stacksize)
dx^=dxStack(stacksize) dy^=dyStack(stacksize)
dir^=dirStack(stacksize)
depth^=depthStack(stacksize)
stage^=stageStack(stacksize)
RETURN
 
PROC DrawDragon(INT x,y,dx,dy BYTE depth)
BYTE dir,stage
INT nx,ny,dx2,dy2,tmp
Push(x,y,dx,dy,1,depth,0)
 
WHILE IsEmpty()=0
DO
Pop(@x,@y,@dx,@dy,@dir,@depth,@stage)
IF depth=0 THEN
Plot(x,y) DrawTo(x+dx,y+dy)
ELSE
IF stage<2 THEN
Push(x,y,dx,dy,dir,depth,stage+1)
FI
nx=dx/2 ny=dy/2
dx2=nx-ny dy2=nx+ny
IF stage=0 THEN
IF dir THEN
Push(x,y,dx2,dy2,1,depth-1,0)
ELSE
Push(x,y,dy2,-dx2,1,depth-1,0)
FI
ELSEIF stage=1 THEN
IF dir THEN
tmp=-dx2 ;to avoid the compiler error
Push(x+dx2,y+dy2,dy2,tmp,0,depth-1,0)
ELSE
Push(x+dy2,y-dx2,dx2,dy2,0,depth-1,0)
FI
FI
FI
OD
RETURN
 
PROC Main()
BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
 
Graphics(8+16)
Color=1
COLOR1=$0C
COLOR2=$02
 
DrawDragon(104,72,128,0,12)
 
DO UNTIL CH#$FF OD
CH=$FF
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Dragon_curve.png Screenshot from Atari 8-bit computer]
 
=={{header|ALGOL 68}}==
 
===Animated===
 
{{trans|python}}
<!-- {{works with|ALGOL 68|Standard - but ''draw'' is not part of the standard prelude}} -->
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - when I figure out how to link to the linux plot lib, then it might work}} -->
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8 algol68g-2.8].}}
'''File: prelude/turtle_draw.a68'''<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
 
STRUCT (REAL x, y, heading, BOOL pen down) turtle;
Line 135 ⟶ 385:
);
 
SKIP</langsyntaxhighlight>'''File: prelude/exception.a68'''<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
 
COMMENT
Line 184 ⟶ 434:
PROC raise unimplemented = (EXCEPTOBJS obj, STRING msg)VOID: IF NOT on unimplemented mend(obj, msg) THEN stop FI;
 
SKIP</langsyntaxhighlight>'''File: test/Dragon_curve.a68'''<langsyntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
Line 269 ⟶ 519:
VOID(system("sleep 1"))
OD;
close (window)</langsyntaxhighlight>
 
Output:
Line 276 ⟶ 526:
|}
Note: each Dragon curve is composed of many smaller dragon curves (shown in a different colour).
 
===L-System===
 
Alternative (monochrome) version using the L-System library.
 
{{libheader|ALGOL 68-l-system}}
Generates an SVG file containing the curve using the L-System. Very similar to the Algol 68 Sierpinski square curve sample. Note the Algol 68 L-System library source code is on a separate page on Rosetta Code - follow the above link and then to the Talk page.
<syntaxhighlight lang="algol68">
BEGIN # Dragon Curve in SVG #
# uses the RC Algol 68 L-System library for the L-System evaluation & #
# interpretation #
 
PR read "lsystem.incl.a68" PR # include L-System utilities #
 
PROC dragon curve = ( STRING fname, INT size, length, order, init x, init y )VOID:
IF FILE svg file;
BOOL open error := IF open( svg file, fname, stand out channel ) = 0
THEN
# opened OK - file already exists and #
# will be overwritten #
FALSE
ELSE
# failed to open the file #
# - try creating a new file #
establish( svg file, fname, stand out channel ) /= 0
FI;
open error
THEN # failed to open the file #
print( ( "Unable to open ", fname, newline ) );
stop
ELSE # file opened OK #
 
REAL x := init x;
REAL y := init y;
INT angle := 0;
put( svg file, ( "<svg xmlns='http://www.w3.org/2000/svg' width='"
, whole( size, 0 ), "' height='", whole( size, 0 ), "'>"
, newline, "<rect width='100%' height='100%' fill='white'/>"
, newline, "<path stroke-width='1' stroke='black' fill='none' d='"
, newline, "M", whole( x, 0 ), ",", whole( y, 0 ), newline
)
);
 
LSYSTEM ssc = ( "F"
, ( "F" -> "F+S"
, "S" -> "F-S"
)
);
STRING curve = ssc EVAL order;
curve INTERPRET ( ( CHAR c )VOID:
IF c = "F" OR c = "S" THEN
x +:= length * cos( angle * pi / 180 );
y +:= length * sin( angle * pi / 180 );
put( svg file, ( " L", whole( x, 0 ), ",", whole( y, 0 ), newline ) )
ELIF c = "+" THEN
angle +:= 90 MODAB 360
ELIF c = "-" THEN
angle -:= 90 MODAB 360
FI
);
put( svg file, ( "'/>", newline, "</svg>", newline ) );
close( svg file )
FI # sierpinski square # ;
 
dragon curve( "dragon.svg", 1200, 5, 12, 400, 200 )
 
END
</syntaxhighlight>
 
=={{header|AmigaE}}==
Example code using mutual recursion can be found in [http://cshandley.co.uk/JasonHulance/beginner_170.html Recursion Example] of "A Beginner's Guide to Amiga E".
 
=={{header|Applesoft BASIC}}==
Apple IIe BASIC code can be found in Thomas Bannon, "Fractals and Transformations", Mathematics Teacher, March 1991, pages 178-185. ([http://www.jstor.org/stable/27967087 At JSTOR].)
 
=={{header|Asymptote}}==
Line 297 ⟶ 613:
=={{header|BASIC}}==
{{works with|QBasic}}
<langsyntaxhighlight lang="qbasic">DIM SHARED angle AS Double
SUB turn (degrees AS Double)
Line 325 ⟶ 641:
PSET (150,180), 0
dragon 400, 12, 1
SLEEP</langsyntaxhighlight>
 
 
Line 335 ⟶ 651:
* https://archive.org/details/byte-magazine-1983-12
 
==={{header|IS-ANSI BASIC}}===
{{trans|QuickBASIC|Internal subprogram is used, so it has access to program (global) variables.}}
<lang IS-BASIC>100 PROGRAM "Dragon.bas"
{{works with|Decimal BASIC}}
110 OPTION ANGLE DEGREES
<syntaxhighlight lang="basic">
120 LET SQ2=SQR(2)
100 PROGRAM DragonCurve
130 GRAPHICS HIRES 2
110 DECLARE SUB Dragon
140 SET PALETTE 0,33
120 SET WINDOW 0, 639, 0, 399
150 PLOT 250,360,ANGLE 0;
130 SET AREA COLOR 1
160 CALL DC(580,0,11)
140 SET COLOR MIX(1) 0, 0, 0
170 DEF DC(D,A,LEV)
150 REM SIN, COS in arrays for PI/4 multipl.
180 IF LEV=0 THEN
160 DIM S(0 TO 7), C(0 TO 7)
190 PLOT FORWARD D;
170 LET QPI = PI / 4
200 ELSE
210180 FOR I = 0 PLOTTO RIGHT A;7
220190 LET CALLS(I) DC= SIN(D/SQ2,45,LEV-1I * QPI)
230200 LET PLOTC(I) LEFT= COS(I 2*A; QPI)
210 NEXT I
240 CALL DC(D/SQ2,-45,LEV-1)
220 REM ** Initialize variables non-local for SUB Dragon.
250 PLOT RIGHT A;
230 LET SQ = SQR(2)
260 END IF
240 LET X = 224
270 END DEF</lang>
250 LET Y = 140
260 LET RotQPi = 0
270 CALL Dragon(256, 15, 1) ! Insize = 2^WHOLE_NUM (looks better)
280 REM ** Subprogram
290 SUB Dragon (Insize, Level, RQ)
300 IF Level <= 1 THEN
310 LET XN = C(RotQPi) * Insize + X
320 LET YN = S(RotQPi) * Insize + Y
330 PLOT LINES: X, 399 - Y; XN, 399 - YN
340 LET X = XN
350 LET Y = YN
360 ELSE
370 LET RotQPi = MOD((RotQPi + RQ), 8)
380 CALL Dragon(Insize / SQ, Level - 1, 1)
390 LET RotQPi = MOD((RotQPi - RQ * 2), 8)
400 CALL Dragon(Insize / SQ, Level - 1, -1)
410 LET RotQPi = MOD((RotQPi + RQ), 8)
420 END IF
430 END SUB
440 END
</syntaxhighlight>
 
==={{header|Applesoft BASIC}}===
Apple IIe BASIC code can be found in Thomas Bannon, "Fractals and Transformations", Mathematics Teacher, March 1991, pages 178-185. ([http://www.jstor.org/stable/27967087 At JSTOR].)
 
==={{header|BASIC256}}===
[[File:Dragon curve BASIC-256.png|220px|thumb|right|Image created by the BASIC-256 script]]
<langsyntaxhighlight lang="basic256"># Version without functions (for BASIC-256 ver. 0.9.6.66)
 
graphsize 390,270
Line 406 ⟶ 746:
level = level + 1
insize = insize*SQ
return</langsyntaxhighlight>
 
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> MODE 8
MOVE 800,400
GCOL 11
Line 427 ⟶ 767:
angle += d*PI/4
ENDIF
ENDPROC</langsyntaxhighlight>
 
==={{header|BefungeChipmunk Basic}}===
{{trans|Commodore BASIC}}
<syntaxhighlight lang="basic">
10 rem Dragon curve
20 rem sin, cos in arrays for pi/4 multipl.
30 dim s(7),c(7)
40 for i = 0 to 7
50 s(i) = sin(i*pi/4) : c(i) = cos(i*pi/4)
60 next i
70 level = 15
80 insize = 256 : rem 2^whole_num (looks better)
90 x = 224 : y = 140
100 sq = sqr(2)
110 rotqpi = 0 : rq = 1
120 dim r(level)
130 graphics 0 : graphics cls
140 gosub 160
150 end
160 rem Dragon
170 rotqpi = rotqpi and 7
180 if level <= 1 then
190 yn = s(rotqpi)*insize+y
200 xn = c(rotqpi)*insize+x
210 graphics moveto x,y : graphics lineto xn,yn
220 x = xn : y = yn
230 else
240 insize = insize*sq/2
250 rotqpi = (rotqpi+rq) and 7
260 level = level-1
270 r(level) = rq : rq = 1
280 gosub 160
290 rotqpi = (rotqpi-r(level)*2) and 7
300 rq = -1
310 gosub 160
320 rq = r(level)
330 rotqpi = (rotqpi+rq) and 7
340 level = level+1
350 insize = insize*sq
360 endif
370 return
</syntaxhighlight>
 
==={{header|Commodore BASIC}}===
{{trans|BASIC256}}
The values of <code>SIN</code> and <code>COS</code> for multiplies of <code>PI / 4</code> are remembered in arrays, so that the program may run (a little) faster.
{{works with|Commodore BASIC|3.5}}
<syntaxhighlight lang="basic">
10 REM DRAGON CURVE
20 REM SIN, COS IN ARRAYS FOR PI/4 MULTIPL.
30 DIM S(7),C(7)
40 QPI=ATN(1):SQ=SQR(2)
50 FOR I=0 TO 7
60 S(I)=SIN(I*QPI):C(I)=COS(I*QPI)
70 NEXT I
80 LEVEL=15
90 INSIZE=128:REM 2^WHOLE_NUM (LOOKS BETTER)
100 X=112:Y=70
110 ROTQPI=0:RQ=1
120 DIM R(LEVEL)
130 GRAPHIC 2,1
140 GOSUB 160
150 END
160 REM DRAGON
170 ROTQPI=ROTQPI AND 7
180 IF LEVEL>1 THEN GO TO 240
190 YN=S(ROTQPI)*INSIZE+Y
200 XN=C(ROTQPI)*INSIZE+X
210 DRAW ,X,Y TO XN,YN
220 X=XN:Y=YN
230 RETURN
240 INSIZE=INSIZE*SQ/2
250 ROTQPI=(ROTQPI+RQ)AND 7
260 LEVEL=LEVEL-1
270 R(LEVEL)=RQ:RQ=1
280 GOSUB 160
290 ROTQPI=(ROTQPI-R(LEVEL)*2)AND 7
300 RQ=-1
310 GOSUB 160
320 RQ=R(LEVEL)
330 ROTQPI=(ROTQPI+RQ)AND 7
340 LEVEL=LEVEL+1
350 INSIZE=INSIZE*SQ
360 RETURN
</syntaxhighlight>
 
==={{header|FreeBASIC}}===
{{trans|BASIC}}
<syntaxhighlight lang="freebasic">Const pi As Double = 4 * Atn(1)
Dim Shared As Double angulo = 0
 
Sub giro (grados As Double)
angulo += grados*pi/180
End Sub
 
Sub dragon (longitud As Double, division As Integer, d As Double)
If division = 0 Then
Line - Step (Cos(angulo)*longitud, Sin(angulo)*longitud), Int(Rnd * 7)
Else
giro d*45
dragon longitud/1.4142136, division-1, 1
giro -d*90
dragon longitud/1.4142136, division-1, -1
giro d*45
End If
End Sub
 
'--- Programa Principal ---
Screen 12
Pset (150,180), 0
dragon 400, 12, 1
Bsave "Dragon_curve_FreeBASIC.bmp",0
Sleep</syntaxhighlight>
 
==={{header|GW-BASIC}}===
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
{{works with|QBasic}}
{{trans|Commodore BASIC}}
<syntaxhighlight lang="qbasic">10 REM Dragon curve
20 REM SIN, COS in arrays for PI/4 multipl.
30 DIM S(7), C(7)
40 QPI = ATN(1): SQ = SQR(2)
50 FOR I = 0 TO 7
60 S(I) = SIN(I * QPI): C(I) = COS(I * QPI)
70 NEXT I
80 LEVEL% = 15
90 INSIZE = 128: REM 2^WHOLE_NUM (looks better)
100 X = 112: Y = 70
110 ROTQPI% = 0: RQ% = 1
120 DIM R%(LEVEL%)
130 SCREEN 2: CLS
140 GOSUB 160
150 END
160 REM ** Dragon
170 ROTQPI% = ROTQPI% AND 7
180 IF LEVEL% > 1 THEN GOTO 240
190 YN = S(ROTQPI%) * INSIZE + Y
200 XN = C(ROTQPI%) * INSIZE + X
210 LINE (2 * X, Y)-(2 * XN, YN): REM For SCREEN 2 doubled x-coords
220 X = XN: Y = YN
230 RETURN
240 INSIZE = INSIZE * SQ / 2
250 ROTQPI% = (ROTQPI% + RQ%) AND 7
260 LEVEL% = LEVEL% - 1
270 R%(LEVEL%) = RQ%: RQ% = 1
280 GOSUB 160
290 ROTQPI% = (ROTQPI% - R%(LEVEL%) * 2) AND 7
300 RQ% = -1
310 GOSUB 160
320 RQ% = R%(LEVEL%)
330 ROTQPI% = (ROTQPI% + RQ%) AND 7
340 LEVEL% = LEVEL% + 1
350 INSIZE = INSIZE * SQ
360 RETURN</syntaxhighlight>
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "Dragon.bas"
110 OPTION ANGLE DEGREES
120 LET SQ2=SQR(2)
130 GRAPHICS HIRES 2
140 SET PALETTE 0,33
150 PLOT 250,360,ANGLE 0;
160 CALL DC(580,0,11)
170 DEF DC(D,A,LEV)
180 IF LEV=0 THEN
190 PLOT FORWARD D;
200 ELSE
210 PLOT RIGHT A;
220 CALL DC(D/SQ2,45,LEV-1)
230 PLOT LEFT 2*A;
240 CALL DC(D/SQ2,-45,LEV-1)
250 PLOT RIGHT A;
260 END IF
270 END DEF</syntaxhighlight>
 
==={{header|Liberty BASIC}}===
{{works with|Just BASIC}}
<syntaxhighlight lang="lb">nomainwin
mainwin 50 20
 
WindowHeight =620
WindowWidth =690
 
open "Graphics library" for graphics as #a
 
#a, "trapclose [quit]"
 
#a "down"
 
Turn$ ="R"
Pace =100
s = 16
 
[again]
print Turn$
 
#a "cls ; home ; north ; down ; fill black"
 
for i =1 to len( Turn$)
v =255 *i /len( Turn$)
#a "color "; v; " 120 "; 255 -v
#a "go "; Pace
if mid$( Turn$, i, 1) ="R" then #a "turn 90" else #a "turn -90"
next i
 
#a "color 255 120 0"
#a "go "; Pace
#a "flush"
 
FlippedTurn$ =""
for i =len( Turn$) to 1 step -1
if mid$( Turn$, i, 1) ="R" then FlippedTurn$ =FlippedTurn$ +"L" else FlippedTurn$ =FlippedTurn$ +"R"
next i
 
Turn$ =Turn$ +"R" +FlippedTurn$
 
Pace =Pace /1.35
 
scan
 
timer 1000, [j]
wait
[j]
timer 0
 
if len( Turn$) <40000 then goto [again]
 
 
wait
 
[quit]
close #a
end</syntaxhighlight>
 
==={{header|MSX Basic}}===
{{trans|Commodore BASIC}}
<syntaxhighlight lang="basic">
10 REM Dragon curve
20 REM SIN, COS in arrays for PI/4 multipl.
30 DIM S(7),C(7)
40 QPI=ATN(1):SQ=SQR(2)
50 FOR I=0 TO 7
60 S(I)=SIN(I*QPI):C(I)=COS(I*QPI)
70 NEXT I
80 LEVEL=15
90 INSIZE=128:REM 2^WHOLE_NUM (looks better)
100 X=80:Y=70
110 ROTQPI=0:RQ=1
120 DIM R(LEVEL)
130 SCREEN 2
140 GOSUB 200
150 OPEN "GRP:" FOR OUTPUT AS #1
160 DRAW "BM 0,184":PRINT #1,"Hit any key to exit."
170 IF INKEY$="" THEN 170
180 CLOSE #1
190 END
200 REM Dragon
210 ROTQPI=ROTQPI AND 7
220 IF LEVEL>1 THEN GOTO 280
230 YN=S(ROTQPI)*INSIZE+Y
240 XN=C(ROTQPI)*INSIZE+X
250 LINE (X,Y)-(XN,YN)
260 X=XN:Y=YN
270 RETURN
280 INSIZE=INSIZE*SQ/2
290 ROTQPI=(ROTQPI+RQ)AND 7
300 LEVEL=LEVEL-1
310 R(LEVEL)=RQ:RQ=1
320 GOSUB 200
330 ROTQPI=(ROTQPI-R(LEVEL)*2)AND 7
340 RQ=-1
350 GOSUB 200
360 RQ=R(LEVEL)
370 ROTQPI=(ROTQPI+RQ)AND 7
380 LEVEL=LEVEL+1
390 INSIZE=INSIZE*SQ
400 RETURN
</syntaxhighlight>
 
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">#SqRt2 = 1.4142136
#SizeH = 800: #SizeV = 550
Global angle.d, px, py, imageNum
 
Procedure turn(degrees.d)
angle + degrees * #PI / 180
EndProcedure
 
Procedure forward(length.d)
Protected w = Cos(angle) * length
Protected h = Sin(angle) * length
LineXY(px, py, px + w, py + h, RGB(255,255,255))
px + w: py + h
EndProcedure
 
Procedure dragon(length.d, split, d.d)
If split = 0
forward(length)
Else
turn(d * 45)
dragon(length / #SqRt2, split - 1, 1)
turn(-d * 90)
dragon(length / #SqRt2, split - 1, -1)
turn(d * 45)
EndIf
EndProcedure
 
OpenWindow(0, 0, 0, #SizeH, #SizeV, "DragonCurve", #PB_Window_SystemMenu)
imageNum = CreateImage(#PB_Any, #SizeH, #SizeV, 32)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageNum))
angle = 0: px = 185: py = 190
If StartDrawing(ImageOutput(imageNum))
dragon(400, 15, 1)
StopDrawing()
SetGadgetState(0, ImageID(imageNum))
EndIf
 
Repeat: Until WaitWindowEvent(10) = #PB_Event_CloseWindow</syntaxhighlight>
 
==={{header|QuickBASIC}}===
{{trans|GW-BASIC|Introduced some parameters in the recursive subroutine (especially for a level and instead of the array simulating a stack).}}
<syntaxhighlight lang="basic">
REM Dragon curve
REM SIN, COS in arrays for PI/4 multipl.
DECLARE SUB Dragon (BYVAL Insize!, BYVAL Level%, BYVAL RQ%)
DIM SHARED S(7), C(7), X, Y, RotQPi%
CONST QPI = .785398163397448# ' PI / 4
FOR I = 0 TO 7
S(I) = SIN(I * QPI)
C(I) = COS(I * QPI)
NEXT I
X = 112: Y = 70
SCREEN 2: CLS
CALL Dragon(128, 15, 1) ' Insize = 2^WHOLE_NUM (looks better)
END
 
SUB Dragon (BYVAL Insize, BYVAL Level%, BYVAL RQ%)
CONST SQ = 1.4142135623731# ' SQR(2)
IF Level% <= 1 THEN
XN = C(RotQPi%) * Insize + X
YN = S(RotQPi%) * Insize + Y
LINE (2 * X, Y)-(2 * XN, YN) ' For SCREEN 2 doubled x-coords
X = XN: Y = YN
ELSE
RotQPi% = (RotQPi% + RQ%) AND 7
CALL Dragon(Insize / SQ, Level% - 1, 1)
RotQPi% = (RotQPi% - RQ% * 2) AND 7
CALL Dragon(Insize / SQ, Level% - 1, -1)
RotQPi% = (RotQPi% + RQ%) AND 7
END IF
END SUB
</syntaxhighlight>
 
==={{header|RapidQ}}===
{{trans|BASIC}}
This implementation displays the Dragon Curve fractal in a [[GUI]] window.
<syntaxhighlight lang="rapidq">DIM angle AS Double
DIM x AS Double, y AS Double
DECLARE SUB PaintCanvas
 
CREATE form AS QForm
Width = 800
Height = 600
CREATE canvas AS QCanvas
Height = form.ClientHeight
Width = form.ClientWidth
OnPaint = PaintCanvas
END CREATE
END CREATE
 
SUB turn (degrees AS Double)
angle = angle + degrees*3.14159265/180
END SUB
SUB forward (length AS Double)
x2 = x + cos(angle)*length
y2 = y + sin(angle)*length
canvas.Line(x, y, x2, y2, &Haaffff)
x = x2: y = y2
END SUB
 
SUB dragon (length AS Double, split AS Integer, d AS Double)
IF split=0 THEN
forward length
ELSE
turn d*45
dragon length/1.4142136, split-1, 1
turn -d*90
dragon length/1.4142136, split-1, -1
turn d*45
END IF
END SUB
 
SUB PaintCanvas
canvas.FillRect(0, 0, canvas.Width, canvas.Height, &H102800)
x = 220: y = 220: angle = 0
dragon 384, 12, 1
END SUB
 
form.ShowModal</syntaxhighlight>
 
==={{header|Run BASIC}}===
<syntaxhighlight lang="runbasic">graphic #g, 600,600
RL$ = "R"
loc = 90
pass = 0
 
[loop]
#g "cls ; home ; north ; down ; fill black"
for i =1 to len(RL$)
v = 255 * i /len(RL$)
#g "color "; v; " 120 "; 255 -v
#g "go "; loc
if mid$(RL$,i,1) ="R" then #g "turn 90" else #g "turn -90"
next i
 
#g "color 255 120 0"
#g "go "; loc
LR$ =""
for i =len( RL$) to 1 step -1
if mid$( RL$, i, 1) ="R" then LR$ =LR$ +"L" else LR$ =LR$ +"R"
next i
 
RL$ = RL$ + "R" + LR$
loc = loc / 1.35
pass = pass + 1
render #g
input xxx
cls
 
if pass < 16 then goto [loop]
end</syntaxhighlight>
<div>[[File:DragonCurveRunBasic.png‎]]</div>
 
==={{header|TI-89 BASIC}}===
{{trans|SVG}}
<syntaxhighlight lang="ti89b">Define dragon = (iter, xform)
Prgm
Local a,b
If iter > 0 Then
dragon(iter-1, xform*[[.5,.5,0][–.5,.5,0][0,0,1]])
dragon(iter-1, xform*[[–.5,.5,0][–.5,–.5,1][0,0,1]])
Else
xform*[0;0;1]→a
xform*[0;1;1]→b
PxlLine floor(a[1,1]), floor(a[2,1]), floor(b[1,1]), floor(b[2,1])
EndIf
EndPrgm
 
FnOff
PlotsOff
ClrDraw
dragon(7, [[75,0,26] [0,75,47] [0,0,1]])</syntaxhighlight>
 
Valid coordinates on the TI-89's graph screen are x 0..76 and y 0..158. This and [[wp:File:Dimensions_fractale_dragon.gif|the outer size of the dragon curve]] were used to choose the position and scale determined by the [[wp:Transformation_matrix#Affine_transformations|transformation matrix]] initially passed to <code>dragon</code> such that the curve will fit onscreen no matter the number of recursions chosen. The height of the curve is 1 unit, so the vertical (and horizontal, to preserve proportions) scale is the height of the screen (rather, one less, to avoid rounding/FP error overrunning), or 75. The curve extends 1/3 unit above its origin, so the vertical translation is (one more than) 1/3 of the scale, or 26. The curve extends 1/3 to the left of its origin, or 25 pixels; the width of the curve is 1.5 units, or 1.5·76 = 114 pixels, and the screen is 159 pixels, so to center it we place the origin at 25 + (159-114)/2 = 47 pixels.
 
==={{header|uBasic/4tH}}===
{{Trans|BBC BASIC}}
uBasic/4tH has neither native support for graphics nor floating point, so everything has to be defined in high level code. All calculations are done in integer arithmetic, scaled by 10K.
<syntaxhighlight lang="ubasic-4th">
Dim @o(5) ' 0 = SVG file, 1 = color, 2 = fillcolor, 3 = pixel, 4 = text
 
' === Begin Program ===
 
Proc _SetColor (FUNC(_Color ("Red"))) ' set the line color to red
Proc _SVGopen ("dragon.svg") ' open the SVG file
Proc _Canvas (525, 625) ' set the canvas size
Proc _Background (FUNC(_Color ("White")))
' we have a white background
a = 475 : b = 175 : t = 14142 : r = 0 : p = 7853
' x,y coordinates, SQRT(2), angle, PI/4
Proc _Dragon (512, 12, 1) ' size, split and direction
Proc _SVGclose ' close SVG file
End
 
_Dragon
Param (3)
If b@ Then ' if split > 0 then recurse
r = r + (c@ * p)
Proc _Dragon ((a@*10000)/t, b@ - 1, 1)
r = r - (c@ * (p+p))
Proc _Dragon ((a@*10000)/t, b@ - 1, -1)
r = r + (c@ * p)
Return
EndIf
' draw a line
Proc _Line (a, b, Set (a, a + (((-FUNC(_COS(r)))*a@)/10000)), Set (b, b + ((FUNC(_SIN(r))*a@)/10000)))
Return
 
' === End Program ===
 
_SetColor Param (1) : @o(1) = a@ : Return
_SVGclose Write @o(0), "</svg>" : Close @o(0) : Return
_color_ Param (1) : Proc _PrintRGB (a@) : Write @o(0), "\q />" : Return
 
_PrintRGB ' print an RBG color in hex
Param (1)
Radix 16
 
If a@ < 0 Then
Write @o(0), "none";
Else
Write @o(0), Show(Str ("#!######", a@));
EndIf
 
Radix 10
Return
 
_Background ' set the background color
Param (1)
 
Write @o(0), "<rect width=\q100%\q height=\q100%\q fill=\q";
Proc _color_ (a@)
Return
 
_Color ' retrieve color code from its name
Param (1)
Local (1)
Radix 16
 
if Comp(a@, "black") = 0 Then
b@ = 000000
else if Comp(a@, "blue") = 0 Then
b@ = 0000ff
else if Comp(a@, "green") = 0 Then
b@ = 00ff00
else if Comp(a@, "cyan") = 0 Then
b@ = 00ffff
else if Comp(a@, "red") = 0 Then
b@ = 0ff0000
else if Comp(a@, "magenta") = 0 Then
b@ = 0ff00ff
else if Comp(a@, "yellow") = 0 Then
b@ = 0ffff00
else if Comp(a@, "white") = 0 Then
b@ = 0ffffff
else if Comp(a@, "none") = 0 Then
b@ = Info ("nil")
else Print "Invalid color" : Raise 1
fi : fi : fi : fi : fi : fi : fi : fi : fi
 
Radix 10
Return (b@)
 
_Line ' draw an SVG line from x1,y1 to x2,y2
Param (4)
 
Write @o(0), "<line x1=\q";d@;"\q y1=\q";c@;
Write @o(0), "\q x2=\q";b@;"\q y2=\q";a@;"\q stroke=\q";
Proc _color_ (@o(1))
Return
 
_Canvas ' set up a canvas x wide and y high
Param (2)
 
Write @o(0), "<svg width=\q";a@;"\q height=\q";b@;"\q viewBox=\q0 0 ";a@;" ";b@;
Write @o(0), "\q xmlns=\qhttp://www.w3.org/2000/svg\q ";
Write @o(0), "xmlns:xlink=\qhttp://www.w3.org/1999/xlink\q>"
Return
 
_SVGopen ' open an SVG file by name
Param (1)
 
If Set (@o(0), Open (a@, "w")) < 0 Then
Print "Cannot open \q";Show (a@);"\q" : Raise 1
Else
Write @o(0), "<?xml version=\q1.0\q encoding=\qUTF-8\q standalone=\qno\q?>"
Write @o(0), "<!DOCTYPE svg PUBLIC \q-//W3C//DTD SVG 1.1//EN\q ";
Write @o(0), "\qhttp://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\q>"
EndIf
Return
' return SIN(x*10K), scaled by 10K
_SIN PARAM(1) : PUSH A@ : LET A@=TOS()<0 : PUSH ABS(POP()%62832)
IF TOS()>31416 THEN A@=A@=0 : PUSH POP()-31416
IF TOS()>15708 THEN PUSH 31416-POP()
PUSH (TOS()*TOS())/10000 : PUSH 10000+((10000*-(TOS()/72))/10000)
PUSH 10000+((POP()*-(TOS()/42))/10000) : PUSH 10000+((POP()*-(TOS()/20))/10000)
PUSH 10000+((POP()*-(POP()/6))/10000) : PUSH (POP()*POP())/10000
IF A@ THEN PUSH -POP()
RETURN
' return COS(x*10K), scaled by 10K
_COS PARAM(1) : PUSH ABS(A@%62832) : IF TOS()>31416 THEN PUSH 62832-POP()
LET A@=TOS()>15708 : IF A@ THEN PUSH 31416-POP()
PUSH TOS() : PUSH (POP()*POP())/10000 : PUSH 10000+((10000*-(TOS()/56))/10000)
PUSH 10000+((POP()*-(TOS()/30))/10000): PUSH 10000+((POP()*-(TOS()/12))/10000)
PUSH 10000+((POP()*-(POP()/2))/10000) : IF A@ THEN PUSH -POP()
RETURN
</syntaxhighlight>
 
==={{header|VBScript}}===
VBScript does'nt have direct access to OS graphics, so I write SVG commands to an HTML file then I display it with the default browser.
A turtle graphics class makes the definition of the curve very simple.
<syntaxhighlight lang="vb">
 
option explicit
'outputs turtle graphics to svg file and opens it
 
const pi180= 0.01745329251994329576923690768489 ' pi/180
const pi=3.1415926535897932384626433832795 'pi
class turtle
dim fso
dim fn
dim svg
dim iang 'radians
dim ori 'radians
dim incr
dim pdown
dim clr
dim x
dim y
 
public property let orient(n):ori = n*pi180 :end property
public property let iangle(n):iang= n*pi180 :end property
public sub pd() : pdown=true: end sub
public sub pu() :pdown=FALSE :end sub
public sub rt(i)
ori=ori - i*iang:
'if ori<0 then ori = ori+pi*2
end sub
public sub lt(i):
ori=(ori + i*iang)
'if ori>(pi*2) then ori=ori-pi*2
end sub
public sub bw(l)
x= x+ cos(ori+pi)*l*incr
y= y+ sin(ori+pi)*l*incr
' ori=ori+pi '?????
end sub
public sub fw(l)
dim x1,y1
x1=x + cos(ori)*l*incr
y1=y + sin(ori)*l*incr
if pdown then line x,y,x1,y1
x=x1:y=y1
end sub
Private Sub Class_Initialize()
setlocale "us"
initsvg
x=400:y=400:incr=100
ori=90*pi180
iang=90*pi180
clr=0
pdown=true
end sub
Private Sub Class_Terminate()
disply
end sub
private sub line (x,y,x1,y1)
svg.WriteLine "<line x1=""" & x & """ y1= """& y & """ x2=""" & x1& """ y2=""" & y1 & """/>"
end sub
 
private sub disply()
dim shell
svg.WriteLine "</svg></body></html>"
svg.close
Set shell = CreateObject("Shell.Application")
shell.ShellExecute fn,1,False
end sub
 
private sub initsvg()
dim scriptpath
Set fso = CreateObject ("Scripting.Filesystemobject")
ScriptPath= Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\"))
fn=Scriptpath & "SIERP.HTML"
Set svg = fso.CreateTextFile(fn,True)
if SVG IS nothing then wscript.echo "Can't create svg file" :vscript.quit
svg.WriteLine "<!DOCTYPE html>" &vbcrlf & "<html>" &vbcrlf & "<head>"
svg.writeline "<style>" & vbcrlf & "line {stroke:rgb(255,0,0);stroke-width:.5}" &vbcrlf &"</style>"
svg.writeline "</head>"&vbcrlf & "<body>"
svg.WriteLine "<svg xmlns=""http://www.w3.org/2000/svg"" width=""800"" height=""800"" viewBox=""0 0 800 800"">"
end sub
end class
 
sub dragon(st,le,dir)
if st=0 then x.fw le: exit sub
x.rt dir
dragon st-1, le/1.41421 ,1
x.rt dir*2
dragon st-1, le/1.41421 ,-1
x.rt dir
end sub
 
dim x
set x=new turtle
x.iangle=45
x.orient=45
x.incr=1
x.x=200:x.y=200
dragon 12,300,1
set x=nothing 'this displays the image
</syntaxhighlight>
 
==={{header|Visual Basic}}===
{{works with|Visual Basic|VB6 Standard}}
<syntaxhighlight lang="vb">Option Explicit
Const Pi As Double = 3.14159265358979
Dim angle As Double
Dim nDepth As Integer
Dim nColor As Long
 
Private Sub Form_Load()
nColor = vbBlack
nDepth = 12
DragonCurve
End Sub
 
Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
If split = 0 Then
xForm.Line -Step(-Cos(angle) * size, Sin(angle) * size), nColor
Else
angle = angle + d * Pi / 4
Call DragonProc(size / Sqr(2), split - 1, 1)
angle = angle - d * Pi / 2
Call DragonProc(size / Sqr(2), split - 1, -1)
angle = angle + d * Pi / 4
End If
End Sub
Sub DragonCurve()
Const xcoefi = 0.74
Const xcoefl = 0.59
xForm.PSet (xForm.Width * xcoefi, xForm.Height / 3), nColor
Call DragonProc(xForm.Width * xcoefl, nDepth, 1)
End Sub</syntaxhighlight>
 
==={{header|Visual Basic .NET}}===
{{works with|Visual Basic .NET|2013}}
<syntaxhighlight lang="vbnet">Option Explicit On
Imports System.Math
 
Public Class DragonCurve
Dim nDepth As Integer = 12
Dim angle As Double
Dim MouseX, MouseY As Integer
Dim CurrentX, CurrentY As Integer
Dim nColor As Color = Color.Black
 
Private Sub DragonCurve_Click(sender As Object, e As EventArgs) Handles Me.Click
SubDragonCurve()
End Sub
 
Sub DrawClear()
Me.CreateGraphics.Clear(Color.White)
End Sub
 
Sub DrawMove(ByVal X As Double, ByVal Y As Double)
CurrentX = X
CurrentY = Y
End Sub
 
Sub DrawLine(ByVal X As Double, ByVal Y As Double)
Dim MyGraph As Graphics = Me.CreateGraphics
Dim PenColor As Pen = New Pen(nColor)
Dim NextX, NextY As Long
NextX = CurrentX + X
NextY = CurrentY + Y
MyGraph.DrawLine(PenColor, CurrentX, CurrentY, NextX, NextY)
CurrentX = NextX
CurrentY = NextY
End Sub
 
Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
If split = 0 Then
DrawLine(-Cos(angle) * size, Sin(angle) * size)
Else
angle = angle + d * PI / 4
DragonProc(size / Sqrt(2), split - 1, 1)
angle = angle - d * PI / 2
DragonProc(size / Sqrt(2), split - 1, -1)
angle = angle + d * PI / 4
End If
End Sub
 
Sub SubDragonCurve()
Const xcoefi = 0.74, xcoefl = 0.59
DrawClear()
DrawMove(Me.Width * xcoefi, Me.Height / 3)
DragonProc(Me.Width * xcoefl, nDepth, 1)
End Sub
 
End Class</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|BASIC256}}
<syntaxhighlight lang="yabasic">w = 390 : h = int(w * 11 / 16)
open window w, h
level = 18 : insize = 247
x = 92 : y = 94
iters = 2^level
qiter = 510/iters
SQ = sqrt(2) : QPI = pi/4
rotation = 0 : iter = 0 : rq = 1.0
dim rqs(level)
color 0,0,0
clear window
dragon()
sub dragon()
if level<=0 then
yn = sin(rotation)*insize + y
xn = cos(rotation)*insize + x
if iter*2<iters then
color 0,iter*qiter,255-iter*qiter
else
color qiter*iter-255,(iters-iter)*qiter,0
end if
line x,y,xn,yn
iter = iter + 1
x = xn : y = yn
return
end if
insize = insize/SQ
rotation = rotation + rq*QPI
level = level - 1
rqs(level) = rq : rq = 1
dragon()
rotation = rotation - rqs(level)*QPI*2
rq = -1
dragon()
rq = rqs(level)
rotation = rotation + rq*QPI
level = level + 1
insize = insize*SQ
return
end sub</syntaxhighlight>
Other solution
<syntaxhighlight lang="yabasic">clear screen
width = 512 : height = 512 : crad = 0.01745329
open window width, height
window origin "cc"
 
x = 75 : y = 120 : level = 18 : iters = 2**level : qiter = 510/iters
 
sub dragon(size, lev, d)
if lev then
dragon(size / sqrt(2), lev - 1, 1)
angle = angle - d * 90
dragon(size / sqrt(2), lev - 1, -1)
else
x = x - cos(angle * crad) * size
y = y + sin(angle * crad) * size
if iter*2<iters then
color 0,iter*qiter,255-iter*qiter
else
color qiter*iter-255,(iters-iter)*qiter,0
endif
line to x, y
iter = iter + 1
endif
end sub
 
dot x, y
dragon(300, level, 1)</syntaxhighlight>
 
==={{header|ZX Spectrum Basic}}===
{{trans|BASIC256}}
<syntaxhighlight lang="zxbasic">10 LET level=15: LET insize=120
20 LET x=80: LET y=70
30 LET sq=SQR (2): LET qpi=PI/4
40 LET rotation=0: LET rq=1
50 DIM r(level)
60 GO SUB 70: STOP
70 REM Dragon
80 IF level>1 THEN GO TO 140
90 LET yn=SIN (rotation)*insize+y
100 LET xn=COS (rotation)*insize+x
110 PLOT x,y: DRAW xn-x,yn-y
120 LET x=xn: LET y=yn
130 RETURN
140 LET insize=insize/sq
150 LET rotation=rotation+rq*qpi
160 LET level=level-1
170 LET r(level)=rq: LET rq=1
180 GO SUB 70
190 LET rotation=rotation-r(level)*qpi*2
200 LET rq=-1
210 GO SUB 70
220 LET rq=r(level)
230 LET rotation=rotation+rq*qpi
240 LET level=level+1
250 LET insize=insize*sq
260 RETURN </syntaxhighlight>
 
=={{header|Befunge}}==
This is loosely based on the [[Dragon_curve#M4|M4]] predicate algorithm, only it produces a more compact ASCII output (which is also a little easier to implement), and it lets you choose the depth of the expansion rather than having to specify the coordinates of the viewing area.
 
In Befunge-93 the 8-bit cell size restricts you to a maximum depth of 15, but in Befunge-98 you should be able go quite a bit deeper before other limits of the implementation come into play.
 
<langsyntaxhighlight lang="befunge">" :htpeD">:#,_&>:00p:2%10p:2/:1+1>\#<1#*-#2:#\_$:1-20p510g2*-*1+610g4vv<v<
| v%2\/3-1$_\#!4#:*#-\#1<\1+1:/4+1g00:\_\#$1<%2/2+1\g02\-1+%-g012\/-*<v"*/
_ >!>0$#0\#$\_-10p20p::00g4/:1+1>\#<1#*-#4:#\_$1-2*3/\2%!>0$#0\#$\_--vv|+2
Line 441 ⟶ 1,678:
>:1+*!60g*!#v_!\!*50g0`*!40gg,::30g40g:2-#^_>>$>>:^:+1g02::\,+55_55+,@v":*
v%2/2+*">~":< ^\-1g05-*">~"/2+*"|~"-%*"|~"\/*"|~":\-*">~"/2+%*"|~"\/*<^<:
>60p\:"~>"*+2/2%60g+2%70p:"kI"*+2/2%60p\:"kI"*+2/2%60g+2%-\70g-"~|"**+"}"^</langsyntaxhighlight>
 
{{out}}
Line 463 ⟶ 1,700:
_|_|_|_| _|_|_|_|
|_| |_| |_| |_|</pre>
 
=={{header|BQN}}==
Works in: [[mlochbaum/BQN]]
 
<code>Rot</code/> is a helper which rotates 90 degrees given direction in <code>𝕨</code>.
 
<code>Turns</code> generates the move sequence of the fractal using the [https://mathworld.wolfram.com/DragonCurve.html Wolfram MathWorld definition:]
 
<blockquote>The curve can be constructed by representing a left turn by 1 and a right turn by 0. The first-order curve is then denoted 1. For higher order curves, append a 1 to the end, then append the string of preceding digits with its middle digit complemented.</blockquote>
 
The drawing may be skewed for some iterations since it is drawn to fit the bounding box.
 
<syntaxhighlight lang="bqn">Rot ← ¬⊸{-⌾(𝕨⊸⊑)⌽𝕩}
Turns ← {{𝕩∾1∾¬⌾((⌊2÷˜≠)⊸⊑)𝕩}⍟𝕩 ⥊1}
 
•Plot´ <˘⍉>+` (<0‿1)(Rot˜)`Turns 3</syntaxhighlight>
[https://mlochbaum.github.io/BQN/try.html#code=Um90IOKGkCDCrOKKuHst4oy+KPCdlajiirjiipEp4oy98J2VqX0KVHVybnMg4oaQIHt78J2VqeKIvjHiiL7CrOKMvigo4oyKMsO3y5ziiaAp4oq44oqRKfCdlal94o2f8J2VqSDipYoxfQoK4oCiUGxvdMK0IDzLmOKNiT4rYCAoPDDigL8xKShSb3TLnClgVHVybnMgNAoK Try It!]
 
=={{header|C}}==
Line 469 ⟶ 1,723:
[[file:dragon-C.png|thumb|center]]
C code that writes PNM of dragon curve. run as <code>a.out [depth] > dragon.pnm</code>. Sample image was with depth 9 (512 pixel length).
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 597 ⟶ 1,851:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
public class DragonCurve : Form
{
private List<int> turns;
private double startingAngle, side;
 
public DragonCurve(int iter)
{
Size = new Size(800, 600);
StartPosition = FormStartPosition.CenterScreen;
DoubleBuffered = true;
BackColor = Color.White;
 
startingAngle = -iter * (Math.PI / 4);
side = 400 / Math.Pow(2, iter / 2.0);
 
turns = getSequence(iter);
}
 
private List<int> getSequence(int iter)
{
var turnSequence = new List<int>();
for (int i = 0; i < iter; i++)
{
var copy = new List<int>(turnSequence);
copy.Reverse();
turnSequence.Add(1);
foreach (int turn in copy)
{
turnSequence.Add(-turn);
}
}
return turnSequence;
}
 
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
 
double angle = startingAngle;
int x1 = 230, y1 = 350;
int x2 = x1 + (int)(Math.Cos(angle) * side);
int y2 = y1 + (int)(Math.Sin(angle) * side);
e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
x1 = x2;
y1 = y2;
foreach (int turn in turns)
{
angle += turn * (Math.PI / 2);
x2 = x1 + (int)(Math.Cos(angle) * side);
y2 = y1 + (int)(Math.Sin(angle) * side);
e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
 
[STAThread]
static void Main()
{
Application.Run(new DragonCurve(14));
}
}</syntaxhighlight>
 
=={{header|C++}}==
Line 603 ⟶ 1,929:
 
This program will generate the curve and save it to your hard drive.
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <iostream>
Line 799 ⟶ 2,125:
}
//-----------------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
 
=={{header|C sharp|C#Clojure}}==
Calculates the absolute location of each step iteratively by bit-twiddling and then prints terminal output with unicode box-drawing characters:
{{trans|Java}}
<syntaxhighlight lang="clojure">(defn i->dir
<lang csharp>using System;
[n]
using System.Collections.Generic;
(mod (Long/bitCount (bit-xor n (bit-shift-right n 1))) 4))
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
(defn safe-bit-or [v bit] (bit-or (or v 0) bit))
public class DragonCurve : Form
{
private List<int> turns;
private double startingAngle, side;
 
(let [steps 511
public DragonCurve(int iter)
{[minx maxx miny maxy] :bbox data :data}
{
(loop [i 0
Size = new Size(800, 600);
[x y] [0 0]
StartPosition = FormStartPosition.CenterScreen;
DoubleBuffered = true; out {}
[minx maxx miny maxy] [0 0 0 0]]
BackColor = Color.White;
(let [dir (i->dir i)
[nx ny] [(+ x (condp = dir 0 1 2 -1 0))
(+ y (condp = dir 1 1 3 -1 0))]
[ob ib] (nth [[8 4][2 1][4 8][1 2]] dir)
out (-> (update-in out [y x] safe-bit-or ob)
(update-in [ny nx] safe-bit-or ib))
bbox [(min minx nx) (max maxx nx)
(min miny ny) (max maxy ny)]]
(if (< i steps)
(recur (inc i) [nx ny] out bbox)
{:data out :bbox bbox})))]
(doseq [y (range miny (inc maxy))]
(->> (for [x (range minx (inc maxx))]
(nth " ╵╷│╴┘┐┤╶└┌├─┴┬┼" (get-in data [y x] 0)))
(apply str)
(println))))
</syntaxhighlight>
 
Output:
startingAngle = -iter * (Math.PI / 4);
side = 400 / Math.Pow(2, iter / 2.0);
 
[[File:Clj-dragon-terminal-screenshot.png|alt=terminal output of Clojure dragon curve program]]
turns = getSequence(iter);
}
 
private List<int> getSequence(int iter)
{
var turnSequence = new List<int>();
for (int i = 0; i < iter; i++)
{
var copy = new List<int>(turnSequence);
copy.Reverse();
turnSequence.Add(1);
foreach (int turn in copy)
{
turnSequence.Add(-turn);
}
}
return turnSequence;
}
 
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
 
double angle = startingAngle;
int x1 = 230, y1 = 350;
int x2 = x1 + (int)(Math.Cos(angle) * side);
int y2 = y1 + (int)(Math.Sin(angle) * side);
e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
x1 = x2;
y1 = y2;
foreach (int turn in turns)
{
angle += turn * (Math.PI / 2);
x2 = x1 + (int)(Math.Cos(angle) * side);
y2 = y1 + (int)(Math.Sin(angle) * side);
e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
 
[STAThread]
static void Main()
{
Application.Run(new DragonCurve(14));
}
}</lang>
 
=={{header|COBOL}}==
{{works with|GnuCOBOL}}
<langsyntaxhighlight lang="cobol"> >>SOURCE FORMAT FREE
*> This code is dedicated to the public domain
identification division.
Line 1,047 ⟶ 2,337:
stop run
.
end program dragon.</langsyntaxhighlight>
 
{{out}}
Line 1,073 ⟶ 2,363:
....... ...
hjkl?q</pre>
 
 
=={{header|Common Lisp}}==
Line 1,080 ⟶ 2,369:
 
The recursive <tt>dragon-part</tt> function draws a curve connecting (0,0) to (1,0); if <var>depth</var> is 0 then the curve is a straight line. <var>bend-direction</var> is either 1 or -1 to specify whether the deviation from a straight line should be to the right or left.
<langsyntaxhighlight lang="lisp">(defpackage #:dragon
(:use #:clim-lisp #:clim)
(:export #:dragon #:dragon-part))
Line 1,098 ⟶ 2,387:
(with-room-for-graphics ()
(with-scaling (t size)
(dragon-part depth 1))))</langsyntaxhighlight>
 
=={{header|D}}==
Line 1,109 ⟶ 2,398:
*rules : (X → X+YF+),(Y → -FX-Y)
*angle : 90°
<langsyntaxhighlight lang="d">import std.stdio, std.string;
 
struct Board {
Line 1,214 ⟶ 2,503:
dragonX(7, t, b); // <- X
writeln(b);
}</langsyntaxhighlight>
{{out}}
<pre> - - - -
Line 1,250 ⟶ 2,539:
===PostScript Output Version===
{{trans|Haskell}}
<langsyntaxhighlight lang="d">import std.stdio, std.string;
 
string drx(in size_t n) pure nothrow {
Line 1,268 ⟶ 2,557:
void main() {
writeln(dragonCurvePS(9)); // Increase this for a bigger curve.
}</langsyntaxhighlight>
 
===On a Bitmap===
Line 1,275 ⟶ 2,564:
First a small "turtle.d" module, useful for other tasks:
 
<langsyntaxhighlight lang="d">module turtle;
 
import bitmap_bresenhams_line_algorithm, grayscale_image, std.math;
Line 1,296 ⟶ 2,585:
y += dy;
}
}</langsyntaxhighlight>
 
Then the implementation is simple:
{{trans|PicoLisp}}
<langsyntaxhighlight lang="d">import grayscale_image, turtle;
 
void drawDragon(Color)(Image!Color img, ref Turtle t, in uint depth,
Line 1,318 ⟶ 2,607:
img.drawDragon(t, 14, 45.0, 3);
img.savePGM("dragon_curve.pgm");
}</langsyntaxhighlight>
 
===With QD===
Line 1,325 ⟶ 2,614:
===With DFL===
See: [[Dragon curve/D/DFL]]
=={{header|Easyprog.onlineDelphi}}==
{{libheader| Winapi.Windows}}
{{libheader| System.SysUtils}}
{{libheader| System.Classes}}
{{libheader| Vcl.Graphics}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Dragon_curve;
 
{$APPTYPE CONSOLE}
[https://easyprog.online/samples/dragon-curve.html Run it]
 
uses
<lang>floatvars
Winapi.Windows,
color 955
System.SysUtils,
System.Classes,
Vcl.Graphics;
 
type
TDragon = class
private
p: TColor;
_sin: TArray<double>;
_cos: TArray<double>;
s: double;
b: TBitmap;
FAsBitmap: TBitmap;
const
sep = 512;
depth = 14;
procedure Dragon(n, a, t: Integer; d, x, y: Double; var b: TBitmap);
public
constructor Create;
destructor Destroy; override;
property AsBitmap: TBitmap read b;
end;
 
{ TDragon }
 
procedure TDragon.Dragon(n, a, t: Integer; d, x, y: Double; var b: TBitmap);
begin
if n <= 1 then
begin
with b.Canvas do
begin
Pen.Color := p;
MoveTo(Trunc(x + 0.5), Trunc(y + 0.5));
LineTo(Trunc(x + d * _cos[a] + 0.5), Trunc(y + d * _sin[a] + 0.5));
exit;
end;
end;
 
d := d * s;
var a1 := (a - t) and 7;
var a2 := (a + t) and 7;
 
dragon(n - 1, a1, 1, d, x, y, b);
dragon(n - 1, a2, -1, d, x + d * _cos[a1], y + d * _sin[a1], b);
end;
 
constructor TDragon.Create;
begin
s := sqrt(2) / 2;
_sin := [0, s, 1, s, 0, -s, -1, -s];
_cos := [1.0, s, 0.0, -s, -1.0, -s, 0.0, s];
p := Rgb(64, 192, 96);
b := TBitmap.create;
 
var width := Trunc(sep * 11 / 6);
var height := Trunc(sep * 4 / 3);
b.SetSize(width, height);
with b.Canvas do
begin
Brush.Color := clWhite;
Pen.Width := 3;
FillRect(Rect(0, 0, width, height));
end;
dragon(14, 0, 1, sep, sep / 2, sep * 5 / 6, b);
end;
 
destructor TDragon.Destroy;
begin
b.Free;
inherited;
end;
 
var
Dragon: TDragon;
 
begin
Dragon := TDragon.Create;
Dragon.AsBitmap.SaveToFile('dragon.bmp');
Dragon.Free;
end.</syntaxhighlight>
 
=={{header|EasyLang}}==
 
[https://easylang.dev/show/#cod=jU7NDoIwDL73Kb7Em4ZZSDDxwMMQNnHJ3HQjCD69ZWDiwYO9tF/7/bQLLkRwzeSsN0+rhytY1TShQVXTLO3EdAujwYSZWt87IzumHegeQwcd2z54JPsycGaEhoIiAPaS8cJFrglFgy4krCb7rNluMw6NYP/rtjyWw2U2Ln3W38FHpEccUOXEAiXKjbTaSa4WzzP/Iy2yVpGijXZilJU4vgE= Run it]
 
<syntaxhighlight lang="text">
color 050
linewidth 0.5
x = 25
Line 1,337 ⟶ 2,720:
angle = 0
#
funcproc dragon size lev% d . .
if lev% = 0
x -= cos angle * size
y += sin angle * size
line x y
else
call dragon size / sqrt 2 lev% - 1 1
angle -= d * 90
call dragon size / sqrt 2 lev% - 1 -1
.
.
call dragon 60 12 1</lang>
</syntaxhighlight>
 
=={{header|Elm}}==
<langsyntaxhighlight lang="elm">import Color exposing (..)
import Collage exposing (..)
import Element exposing (..)
Line 1,444 ⟶ 2,828:
, update = update
, subscriptions = subscriptions
}</langsyntaxhighlight>
 
Link to live demo: http://dc25.github.io/dragonCurveElm
Line 1,451 ⟶ 2,835:
Drawing ascii art characters into a buffer using <code>[http://www.gnu.org/software/emacs/manual/html_node/emacs/Picture-Mode.html picture-mode]</code>
 
<syntaxhighlight lang="lisp">(defun dragon-ensure-line-above ()
<lang lisp>(require 'cl) ;; Emacs 22 and earlier for `ignore-errors'
 
(defun dragon-ensure-line-above ()
"If point is in the first line of the buffer then insert a new line above."
(when (= (line-beginning-position) (point-min))
Line 1,542 ⟶ 2,924:
(goto-char (point-min)))
 
(dragon-picture 128 2)</langsyntaxhighlight>
 
{{out}}
 
<pre>
Line 1,570 ⟶ 2,954:
| | | |
+-+ +-+</pre>
 
 
=={{header|ERRE}}==
Graphic solution with PC.LIB library
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM DRAGON
 
Line 1,622 ⟶ 3,005:
GET(A$)
END PROGRAM
</syntaxhighlight>
</lang>
 
=={{header|F Sharp|F#}}==
Using {{libheader|Windows Presentation Foundation}} for visualization:
<langsyntaxhighlight lang="fsharp">open System.Windows
open System.Windows.Media
 
Line 1,646 ⟶ 3,029:
[ for a, b in nest 13 step (seq [Point(0.0, 0.0), Point(1.0, 0.0)]) ->
PathFigure(a, [(LineSegment(b, true) :> PathSegment)], false) ]
(Application()).Run(Window(Content=Controls.Viewbox(Child=path))) |> ignore</langsyntaxhighlight>
 
=={{header|Factor}}==
A translation of the BASIC example, using OpenGL, drawing with HSV coloring similar to the C example.
 
<syntaxhighlight lang="factor">
<lang Factor>
USING: accessors colors colors.hsv fry kernel locals math
math.constants math.functions opengl.gl typed ui ui.gadgets
Line 1,705 ⟶ 3,088:
 
MAIN: dragon-window
</syntaxhighlight>
</lang>
 
=={{header|Forth}}==
{{works with|bigFORTH}}
<langsyntaxhighlight lang="forth">include turtle.fs
 
2 value dragon-step
Line 1,722 ⟶ 3,105:
 
home clear
10 45 dragon</langsyntaxhighlight>
{{works with|4tH}}
Basically the same code as the BigForth version.
[[file:4tHdragon.png|right|thumb|Output png]]
<langsyntaxhighlight lang="forth">include lib/graphics.4th
include lib/gturtle.4th
 
Line 1,745 ⟶ 3,128:
clear-screen 50 95 turtle!
xpendown 13 45 dragon
s" 4tHdragon.ppm" save_image</langsyntaxhighlight>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Dragon_curve}}
 
'''Solution'''
 
=== Recursive ===
 
[[File:Fōrmulæ - Dragon curve 01.png]]
 
'''Test case.''' Creating dragon curves from orders 2 to 13
 
[[File:Fōrmulæ - Dragon curve 02.png]]
 
[[File:Fōrmulæ - Dragon curve 03.png]]
 
=== L-system ===
 
There are generic functions written in Fōrmulæ to compute an L-system in the page [[L-system#Fōrmulæ | L-system]].
 
The program that creates a Dragon curve is:
 
[[File:Fōrmulæ - L-system - Dragon curve 01.png]]
 
[[File:Fōrmulæ - L-system - Dragon curve 02.png]]
 
Rounded version:
 
[[File:Fōrmulæ - L-system - Dragon curve (rounded) 01.png]]
 
[[File:Fōrmulæ - L-system - Dragon curve (rounded) 02.png]]
 
=={{header|Gnuplot}}==
Line 1,751 ⟶ 3,166:
Implemented by "parametric" mode running an index t through the desired number of curve segments with X,Y position calculated for each. The "lines" plot joins them up.
 
<langsyntaxhighlight lang="gnuplot"># Return the position of the highest 1-bit in n.
# The least significant bit is position 0.
# For example n=13 is binary "1101" and the high bit is pos=3.
Line 1,801 ⟶ 3,216:
set parametric
set key off
plot real(dragon(t)),imag(dragon(t)) with lines</langsyntaxhighlight>
 
===Version #2.===
Line 1,812 ⟶ 3,227:
 
;plotdcf.gp:
<langsyntaxhighlight lang="gnuplot">
## plotdcf.gp 1/11/17 aev
## Plotting a Dragon curve fractal to the png-file.
Line 1,833 ⟶ 3,248:
plot -100
set output
</syntaxhighlight>
</lang>
;Plotting 3 Dragon curve fractals:
<langsyntaxhighlight lang="gnuplot">
## pDCF.gp 1/11/17 aev
## Plotting 3 Dragon curve fractals.
Line 1,856 ⟶ 3,271:
filename = "DCF"; ttl = "Dragon curve fractal, order ".ord;
load "plotdcf.gp"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 1,862 ⟶ 3,277:
2. 3 plotted png-files: DCF11gp, DCF13gp and DCF15gp
</pre>
 
=={{header|Gri}}==
Recursively by a dragon curve comprising two smaller dragons drawn towards a midpoint.
 
<lang Gri>`Draw Dragon [ from .x1. .y1. to .x2. .y2. [level .level.] ]'
Draw a dragon curve going from .x1. .y1. to .x2. .y2. with recursion
depth .level.
 
The total number of line segments for the recursion is 2^level.
level=0 is a straight line from x1,y1 to x2,y2.
 
The default for x1,y1 and x2,y2 is to draw horizontally from 0,0
to 1,0.
{
new .x1. .y1. .x2. .y2. .level.
.x1. = \.word3.
.y1. = \.word4.
.x2. = \.word6.
.y2. = \.word7.
.level. = \.word9.
if {rpn \.words. 5 >=}
.x2. = 1
.y2. = 0
end if
if {rpn \.words. 7 >=}
.level. = 6
end if
if {rpn 0 .level. <=}
draw line from .x1. .y1. to .x2. .y2.
else
.level. = {rpn .level. 1 -}
 
# xmid,ymid is half way between x1,y1 and x2,y2 and up at
# right angles away.
#
# xmid,ymid xmid = (x1+x2 + y2-y1)/2
# ^ ^ ymid = (x1-x2 + y1+y2)/2
# / . \
# / . \
# x1,y1 ........... x2,y2
#
new .xmid. .ymid.
.xmid. = {rpn .x1. .x2. + .y2. .y1. - + 2 /}
.ymid. = {rpn .x1. .x2. - .y1. .y2. + + 2 /}
# The recursion is a level-1 dragon from x1,y1 to the midpoint
# and the same from x2,y2 to the midpoint (the latter
# effectively being a revered dragon.)
#
Draw Dragon from .x1. .y1. to .xmid. .ymid. level .level.
Draw Dragon from .x2. .y2. to .xmid. .ymid. level .level.
delete .xmid. .ymid.
end if
delete .x1. .y1. .x2. .y2. .level.
}
 
# Dragon curve from 0,0 to 1,0 extends out by 1/3 at the ends, so
# extents -0.5 to +1.5 for a bit of margin. The Y extent is the same
# size 2 to make the graph square.
set x axis -0.5 1.5 .25
set y axis -1 1 .25
 
Draw Dragon</lang>
 
=={{header|Go}}==
[[file:GoDragon.png|right|thumb|Output png]]
Version using standard image libriary is an adaptation of the version below using the Bitmap task. The only major change is that line drawing code was needed. See comments in code.
<langsyntaxhighlight lang="go">package main
 
import (
Line 2,008 ⟶ 3,356:
dragon(n-1, a1, 1, d, x, y)
dragon(n-1, a2, -1, d, x+d*cos[a1], y+d*sin[a1])
}</langsyntaxhighlight>
Original version written to Bitmap task:
<langsyntaxhighlight lang="go">package main
 
// Files required to build supporting package raster are found in:
Line 2,052 ⟶ 3,400:
dragon(n-1, a1, 1, d, x, y)
dragon(n-1, a2, -1, d, x+d*cos[a1], y+d*sin[a1])
}</langsyntaxhighlight>
 
=={{header|Gri}}==
Recursively by a dragon curve comprising two smaller dragons drawn towards a midpoint.
 
<syntaxhighlight lang="gri">`Draw Dragon [ from .x1. .y1. to .x2. .y2. [level .level.] ]'
Draw a dragon curve going from .x1. .y1. to .x2. .y2. with recursion
depth .level.
 
The total number of line segments for the recursion is 2^level.
level=0 is a straight line from x1,y1 to x2,y2.
 
The default for x1,y1 and x2,y2 is to draw horizontally from 0,0
to 1,0.
{
new .x1. .y1. .x2. .y2. .level.
.x1. = \.word3.
.y1. = \.word4.
.x2. = \.word6.
.y2. = \.word7.
.level. = \.word9.
if {rpn \.words. 5 >=}
.x2. = 1
.y2. = 0
end if
if {rpn \.words. 7 >=}
.level. = 6
end if
if {rpn 0 .level. <=}
draw line from .x1. .y1. to .x2. .y2.
else
.level. = {rpn .level. 1 -}
 
# xmid,ymid is half way between x1,y1 and x2,y2 and up at
# right angles away.
#
# xmid,ymid xmid = (x1+x2 + y2-y1)/2
# ^ ^ ymid = (x1-x2 + y1+y2)/2
# / . \
# / . \
# x1,y1 ........... x2,y2
#
new .xmid. .ymid.
.xmid. = {rpn .x1. .x2. + .y2. .y1. - + 2 /}
.ymid. = {rpn .x1. .x2. - .y1. .y2. + + 2 /}
# The recursion is a level-1 dragon from x1,y1 to the midpoint
# and the same from x2,y2 to the midpoint (the latter
# effectively being a revered dragon.)
#
Draw Dragon from .x1. .y1. to .xmid. .ymid. level .level.
Draw Dragon from .x2. .y2. to .xmid. .ymid. level .level.
delete .xmid. .ymid.
end if
delete .x1. .y1. .x2. .y2. .level.
}
 
# Dragon curve from 0,0 to 1,0 extends out by 1/3 at the ends, so
# extents -0.5 to +1.5 for a bit of margin. The Y extent is the same
# size 2 to make the graph square.
set x axis -0.5 1.5 .25
set y axis -1 1 .25
 
Draw Dragon</syntaxhighlight>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.List
import Graphics.Gnuplot.Simple
 
Line 2,072 ⟶ 3,487:
where lxs = last xs
 
dragoncurve = iterate vmoot pl</langsyntaxhighlight>
For plotting I use the gnuplot interface module from [http://hackage.haskell.org/packages/hackage.html hackageDB]
 
Line 2,079 ⟶ 3,494:
 
String rewrite, and outputs a postscript:
<langsyntaxhighlight lang="haskell">x 0 = ""
x n = (x$n-1)++" +"++(y$n-1)++" f +"
y 0 = ""
Line 2,089 ⟶ 3,504:
"f", x n, " stroke showpage"]
 
main = putStrLn $ dragon 14</langsyntaxhighlight>
 
=={{header|HicEst}}==
A straightforward approach, since HicEst does not know recursion (rarely needed in daily work)
<langsyntaxhighlight lang="hicest"> CHARACTER dragon
 
1 DLG(NameEdit=orders,DNum, Button='&OK', TItle=dragon) ! input orders
Line 2,122 ⟶ 3,537:
GOTO 1 ! this is to stimulate a discussion
 
END</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
The following implements a Heighway Dragon using the [[Lindenmayer system]]. It's based on the ''linden'' program in the Icon Programming Library.
<langsyntaxhighlight Iconlang="icon">link linddraw,wopen
 
procedure main()
Line 2,145 ⟶ 3,560:
WriteImage("dragon-unicon" || ".gif") # save the image
WDone()
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 2,153 ⟶ 3,568:
 
=={{header|J}}==
<langsyntaxhighlight lang="j">require 'plot'
start=: 0 0,: 1 0
step=: ],{: +"1 (0 _1,: 1 0) +/ .*~ |.@}: -"1 {:
plot <"1 |: step^:13 start</langsyntaxhighlight>
In English: Start with a line segment. For each step of iteration, retrace that geometry backwards, but oriented 90 degrees about its original end point. To show the curve you need to pick some arbitrary number of iterations.
 
Line 2,164 ⟶ 3,579:
 
For a more colorful display, with a different color for the geometry introduced at each iteration, replace that last line of code with:
<langsyntaxhighlight lang="j">([:pd[:<"1|:)every'reset';|.'show';step&.>^:(i.17)<start</langsyntaxhighlight>
 
<div style="border: 1px solid #FFFFFF; overflow: auto; width: 100%"></div>
Line 2,173 ⟶ 3,588:
 
Giving the code
<langsyntaxhighlight lang="j">require 'plot'
f1=.*&(-:1j1)
f2=.[: -. *&(-:1j_1)
plot (f1,}.@|.@f2)^:12 ]0 1</langsyntaxhighlight>
 
Where both functions are applied successively to starting complex values of 0 and 1.
Line 2,182 ⟶ 3,597:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.awt.Color;
import java.awt.Graphics;
import java.util.*;
Line 2,237 ⟶ 3,652:
new DragonCurve(14).setVisible(true);
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
===VersionES5 #1.plus HTML DOM===
====Version #1.====
{{works with|Chrome 8.0}}
I'm sure this can be simplified further, but I have this working [http://kevincantu.org/code/dragon/dragon.html here]!
 
Though there is an impressive SVG example further below, this uses JavaScript to recurse through the expansion and simply displays each line with SVG. It is invoked as a method <code>DRAGON.fractal(...)</code> as described.
<langsyntaxhighlight lang="javascript">var DRAGON = (function () {
// MATRIX MATH
// -----------
Line 2,341 ⟶ 3,757:
};
 
}());</langsyntaxhighlight>
 
My current demo page includes the following to invoke this:
<langsyntaxhighlight lang="html">...
<script src='./dragon.js'></script>
...
Line 2,353 ⟶ 3,769:
DRAGON.fractal('fractal', [100,300], [500,300], 15, false, 700);
</script>
...</langsyntaxhighlight>
 
====Version #2.====
{{works with|Chrome}}
[[File:DC11.png|200px|right|thumb|Output DC11.png]]
[[File:DC19.png|200px|right|thumb|Output DC19.png]]
[[File:DC25.png|200px|right|thumb|Output DC25.png]]
<langsyntaxhighlight lang="html">
<!-- DragonCurve.html -->
<html>
Line 2,403 ⟶ 3,819:
</body>
</html>
</syntaxhighlight>
</lang>
'''Testing cases:'''
<pre>
Line 2,423 ⟶ 3,839:
<pre>
Page with different plotted Dragon curves. Right-clicking on the canvas you can save each of them
as a png-file. </pre>
 
</pre>
===ES6===
 
Declarative definition of an SVG file, in terms of functional primitives.
(To test, generate and save SVG as file, and open in a browser or graphics application).
 
(Pure JS, without HTML or DOM)
<syntaxhighlight lang="javascript">(() => {
'use strict';
 
// ------------------ DRAGON CURVE -------------------
 
// dragonCurve :: [[Int]] -> [[Int]]
const dragonCurve = xs => {
const
pivot = op => map(
zipWith(op)(last(xs))
),
r90 = [
[0, 1],
[-1, 0]
];
return compose(
append(xs),
pivot(add),
flip(matrixMultiply)(r90),
pivot(subtract),
reverse,
init
)(xs);
};
 
 
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
// SVG of 12th iteration.
console.log(
svgFromPointLists(512)(512)(
index(iterate(dragonCurve)([
[0, 0],
[0, -1]
]))(12)
)
);
 
 
// ----------------------- SVG -----------------------
 
// svgFromPointLists :: Int -> Int ->
// [[(Int, Int)]] -> String
const svgFromPointLists = cw => ch =>
xyss => {
const
polyline = xs =>
`<polyline points="${unwords(concat(xs).map(showJSON))}"/>`,
[x, y, mx, my] = ap([minimum, maximum])(
Array.from(unzip(concat(xyss)))
),
[wd, hd] = map(x => Math.floor(x / 10))([
mx - x, my - y
]);
return unlines([
'<?xml version="1.0" encoding="UTF-8"?>',
unwords([
'<svg',
`width="${cw}" height="${ch}"`,
`viewBox="${x - wd} ${y - hd} ${12 * wd} ${12 * hd}"`,
'xmlns="http://www.w3.org/2000/svg">'
]),
'<g stroke-width="0.2" stroke="red" fill="none">',
unlines(map(polyline)(xyss)),
'</g>',
'</svg>'
]);
};
 
 
// ---------------- GENERIC FUNCTIONS ----------------
 
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
 
 
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
 
 
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
 
 
// add (+) :: Num a => a -> a -> a
const add = a =>
// Curried addition.
b => a + b;
 
 
// ap (<*>) :: [(a -> b)] -> [a] -> [b]
const ap = fs =>
// The sequential application of each of a list
// of functions to each of a list of values.
xs => fs.flatMap(
f => xs.map(f)
);
 
// append (++) :: [a] -> [a] -> [a]
// append (++) :: String -> String -> String
const append = xs =>
// A list or string composed by
// the concatenation of two others.
ys => xs.concat(ys);
 
 
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
 
 
// concat :: [[a]] -> [a]
const concat = xs => [].concat(...xs);
 
 
// dotProduct :: Num a => [[a]] -> [[a]] -> [[a]]
const dotProduct = xs =>
compose(sum, zipWith(mul)(xs));
 
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
 
 
// flip :: (a -> b -> c) -> b -> a -> c
const flip = f =>
x => y => f(y)(x);
 
 
// index (!!) :: [a] -> Int -> Maybe a
// index (!!) :: Generator (a) -> Int -> Maybe a
// index (!!) :: String -> Int -> Maybe Char
const index = xs =>
i => (
drop(i)(xs),
take(1)(xs)
);
 
 
// drop :: Int -> [a] -> [a]
// drop :: Int -> Generator [a] -> Generator [a]
// drop :: Int -> String -> String
const drop = n =>
xs => Infinity > length(xs) ? (
xs.slice(n)
) : (take(n)(xs), xs);
 
 
// init :: [a] -> [a]
const init = xs =>
// All elements of a list except the last.
0 < xs.length ? (
xs.slice(0, -1)
) : undefined;
 
 
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
function* (x) {
let v = x;
while (true) {
yield(v);
v = f(v);
}
};
 
 
// last :: [a] -> a
const last = xs =>
// The last item of a list.
0 < xs.length ? xs.slice(-1)[0] : undefined;
 
 
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
 
 
// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => xs.map(f);
 
 
// matrixMultiply :: Num a => [[a]] -> [[a]] -> [[a]]
const matrixMultiply = a =>
b => {
const cols = transpose(b);
return map(
compose(
flip(map)(cols),
dotProduct
)
)(a);
};
 
// minimum :: Ord a => [a] -> a
const minimum = xs =>
0 < xs.length ? (
xs.slice(1)
.reduce((a, x) => x < a ? x : a, xs[0])
) : undefined;
 
 
// maximum :: Ord a => [a] -> a
const maximum = xs =>
// The largest value in a non-empty list.
0 < xs.length ? (
xs.slice(1).reduce(
(a, x) => x > a ? (
x
) : a, xs[0]
)
) : undefined;
 
 
// mul (*) :: Num a => a -> a -> a
const mul = a =>
b => a * b;
 
 
// reverse :: [a] -> [a]
const reverse = xs =>
xs.slice(0).reverse();
 
 
// showJSON :: a -> String
const showJSON = x =>
// Indented JSON representation of the value x.
JSON.stringify(x, null, 2);
 
 
// subtract :: Num -> Num -> Num
const subtract = x =>
y => y - x;
 
 
// sum :: [Num] -> Num
const sum = xs =>
// The numeric sum of all values in xs.
xs.reduce((a, x) => a + x, 0);
 
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => 'GeneratorFunction' !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
 
// transpose :: [[a]] -> [[a]]
const transpose = rows =>
// The columns of the input transposed
// into new rows.
// Simpler version of transpose, assuming input
// rows of even length.
0 < rows.length ? rows[0].map(
(x, i) => rows.flatMap(
x => x[i]
)
) : [];
 
 
// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join('\n');
 
 
// until :: (a -> Bool) -> (a -> a) -> a -> a
const until = p => f => x => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
 
 
// unwords :: [String] -> String
const unwords = xs =>
// A space-separated string derived
// from a list of words.
xs.join(' ');
 
 
// unzip :: [(a,b)] -> ([a],[b])
const unzip = xys =>
xys.reduce(
(ab, xy) => Tuple(ab[0].concat(xy[0]))(
ab[1].concat(xy[1])
),
Tuple([])([])
);
 
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => {
const
lng = Math.min(length(xs), length(ys)),
vs = take(lng)(ys);
return take(lng)(xs)
.map((x, i) => f(x)(vs[i]));
};
 
// MAIN ---
return main();
})();</syntaxhighlight>
 
=={{header|jq}}==
{{works with|jq|1.4}}
'''Works with gojq, the Go implementation of jq'''
 
The programs given here generate SVG code that can be
viewed directly in a browser, at least if the file suffix is .svg.
 
The first program uses simple turtle graphics and an L-system;
the second is based on the fractalMakeDragon example in [[#Javascript|Javascript]].
 
===L-System===
See [[Peano_curve#Simple_Turtle_Graphics | Simple Turtle Graphics]]
for the simple-turtle.jq module used in this entry. The `include`
statement assumes the file is in the pwd.
<syntaxhighlight lang="jq">include "simple-turtle" {search: "."};
 
def rules:
{ F: "F+S",
S: "F-S" };
 
def dragon($count):
rules as $rules
| def p($count):
if $count <= 0 then .
else gsub("S"; "s") | gsub("F"; $rules["F"]) | gsub("s"; $rules["S"])
| p($count-1)
end;
"F" | p($count) ;
 
def interpret($x):
if $x == "+" then turtleRotate(90)
elif $x == "-" then turtleRotate(-90)
elif $x == "F" then turtleForward(4)
elif $x == "S" then turtleForward(4)
else .
end;
 
def dragon_curve($n):
dragon($n)
| split("")
| reduce .[] as $action (turtle([200,300]) | turtleDown;
interpret($action) ) ;
 
dragon_curve(15)
| path("none"; "red"; "0.1") | svg(1700)</syntaxhighlight>
 
===fractalMakeDragon===
 
The following is based on the JavaScript example, with some variations, notably:
* the last argument of the main function allows CSS style elements to be specified
Line 2,442 ⟶ 4,258:
# left if true, make new point on left; if false, then on right
# css a JSON object optionally specifying "stroke" and "stroke-width"
<langsyntaxhighlight lang="jq"># MATRIX MATH
def mult(m; v):
[ m[0][0] * v[0] + m[0][1] * v[1],
Line 2,497 ⟶ 4,313:
grow(ptA; ptC; steps; left),
"'/>",
"</svg>";</langsyntaxhighlight>
'''Example''':
<langsyntaxhighlight lang="jq"># Default values are provided for the last argument
fractalMakeDragon("roar"; [100,300]; [500,300]; 15; false; {})</langsyntaxhighlight>
{{out}}
[https://drive.google.com/file/d/0BwMI1gZaY2-MYW1oanVfMVRTVms/view SVG converted to png]
 
The command to generate the SVG and the first few lines of output are as follows:
<langsyntaxhighlight lang="sh">$ jq -n -r -f dragon.jq
<svg width='100%' height='100% '
id='roar'
Line 2,516 ⟶ 4,332:
M259.375 218.75L262.5 218.75
...
</syntaxhighlight>
</lang>
 
=={{header|Julia}}==
Line 2,522 ⟶ 4,338:
Code uses Luxor library[https://juliagraphics.github.io/Luxor.jl/latest/turtle.html].
 
<langsyntaxhighlight lang="julia">
using Luxor
function dragon(turtle::Turtle, level=4, size=200, direction=45)
Line 2,541 ⟶ 4,357:
finish()
preview()
</syntaxhighlight>
</lang>
[[File:Plot 1.png|frameless|center]]
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.awt.Color
Line 2,599 ⟶ 4,416:
fun main(args: Array<String>) {
DragonCurve(14).isVisible = true
}</langsyntaxhighlight>
 
=={{header|Liberty BASICLambdatalk}}==
1) two twinned recursive functions
<lang lb>nomainwin
mainwin 50 20
 
<syntaxhighlight lang="scheme">
WindowHeight =620
{def dcr
WindowWidth =690
{lambda {:step :length}
{let { {:step {- :step 1}}
{:length {/ :length 1.41421}}
} {if {> :step 0}
then T45
{dcr :step :length}
T-90
{dcl :step :length}
T45
else T45
M:length
T-90
M:length
T45}
}}}
-> dcr
{def dcl
{lambda {:step :length}
{let { {:step {- :step 1}}
{:length {/ :length 1.41421}}
} {if {> :step 0}
then T-45
{dcr :step :length}
T90
{dcl :step :length}
T-45
else T-45
M:length
T90
M:length
T-45}
}}}
-> dcl
</syntaxhighlight>
The word Tθ rotates the drawing direction of the pen from θ degrees
and the word Md moves it on d pixels.
Writing {dcr 10 360} outputs 4093 words begining with
T45 T45 T45 T45 T45 T45 T45 T45 T45 T45 M11.250283388970585
T-90 M11.250283388970585 T45 T-90 T-45 M11.250283388970585 T90 M11.250283388970585 ...
 
2) the SVG context
open "Graphics library" for graphics as #a
 
Lambdatalk comes with a primitive, turtle, translating the previous sequence of words into
#a, "trapclose [quit]"
a sequence of SVG points [x0 y0 x1 y2 ... xn yn] feeding the "d" attribute of a SVG path.
 
3) drawing three dragon curves [2,6,10] of decreasing width:
#a "down"
<syntaxhighlight lang="scheme">
{svg
{@ width="580px" height="580px"
style="box-shadow:0 0 8px #888;"}
{path {@ d="M {turtle 130 130 0 {dcr 2 360}}" {stroke 20 #ccc}}}
{path {@ d="M {turtle 130 130 0 {dcr 6 360}}" {stroke 10 #888}}}
{path {@ d="M {turtle 130 130 0 {dcr 10 360}}" {stroke 1 #000}}}
}
 
where
Turn$ ="R"
{def stroke Pace =100
{lambda {:w :c}
s = 16
fill="transparent" stroke=":c" stroke-width=":w"}}
 
-> stroke
[again]
</syntaxhighlight>
print Turn$
The output can be seen in http://lambdaway.free.fr/lambdawalks/?view=dragon
 
#a "cls ; home ; north ; down ; fill black"
 
for i =1 to len( Turn$)
v =255 *i /len( Turn$)
#a "color "; v; " 120 "; 255 -v
#a "go "; Pace
if mid$( Turn$, i, 1) ="R" then #a "turn 90" else #a "turn -90"
next i
 
#a "color 255 120 0"
#a "go "; Pace
#a "flush"
 
FlippedTurn$ =""
for i =len( Turn$) to 1 step -1
if mid$( Turn$, i, 1) ="R" then FlippedTurn$ =FlippedTurn$ +"L" else FlippedTurn$ =FlippedTurn$ +"R"
next i
 
Turn$ =Turn$ +"R" +FlippedTurn$
 
Pace =Pace /1.35
 
scan
 
timer 1000, [j]
wait
[j]
timer 0
 
if len( Turn$) <40000 then goto [again]
 
 
wait
 
[quit]
close #a
end</lang>
 
=={{header|Logo}}==
===Recursive===
<langsyntaxhighlight lang="logo">to dcr :step :length
make "step :step - 1
make "length :length / 1.41421
Line 2,673 ⟶ 4,501:
if :step > 0 [lt 45 dcr :step :length rt 90 dcl :step :length lt 45]
if :step = 0 [lt 45 fd :length rt 90 fd :length lt 45]
end</langsyntaxhighlight>
The program can be started using <tt>dcr 4 300</tt> or <tt>dcl 4 300</tt>.
 
Or removing duplication:
<langsyntaxhighlight lang="logo">to dc :step :length :dir
if :step = 0 [fd :length stop]
rt :dir
Line 2,687 ⟶ 4,515:
to dragon :step :length
dc :step :length 45
end</langsyntaxhighlight>
An alternative approach by using sentence-like grammar using four productions o->on, n->wn, w->ws, s->os. O, S, N and W mean cardinal points.
<langsyntaxhighlight lang="logo">to O :step :length
if :step=1 [Rt 90 fd :length Lt 90] [O (:step - 1) (:length / 1.41421) N (:step - 1) (:length / 1.41421)]
end
Line 2,703 ⟶ 4,531:
to S :step :length
if :step=1 [Rt 180 fd :length Lt 180] [O (:step - 1) (:length / 1.41421) S (:step - 1) (:length / 1.41421)]
end</langsyntaxhighlight>
 
===Iterative===
Line 2,709 ⟶ 4,537:
 
{{works with|UCB Logo}}
<langsyntaxhighlight lang="logo">; Return the bit above the lowest 1-bit in :n.
; If :n = binary "...z100..00" then the return is "z000..00".
; Eg. n=22 is binary 10110 the lowest 1-bit is the "...1." and the return is
Line 2,732 ⟶ 4,560:
end
 
dragon 256</langsyntaxhighlight>
 
<langsyntaxhighlight lang="logo">; Draw :steps many segments of the dragon curve, with corners chamfered
; off with little 45-degree diagonals.
; Done this way the vertices don't touch.
Line 2,753 ⟶ 4,581:
end
 
dragon.chamfer 256</langsyntaxhighlight>
 
=={{header|Lua}}==
{{works with|Lua|5.1.4}}
Could be made much more compact, but this was written for speed. It has two rendering modes, one which renders the curve in text mode (default,) and one which just dumps all the coordinates for use by an external rendering application.
<langsyntaxhighlight Lualang="lua">function dragon()
local l = "l"
local r = "r"
Line 2,850 ⟶ 4,678:
 
--replace this line with dump_points() to output a list of coordinates:
render_text_mode() </langsyntaxhighlight>
Output:
<pre>
Line 2,900 ⟶ 4,728:
**** ****
</pre>
 
=={{header|M2000 Interpreter}}==
[https://1.bp.blogspot.com/-KTPvvri-EAQ/W_7C9ug1WFI/AAAAAAAAHck/NeWCuJ0GXpkMwkANM6i6UJRgZxqig_mXgCLcBGAs/s1600/dragon_curve.png Image]
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
def double angle, d45, d90, change=5000
Line 2,971 ⟶ 4,800:
Checkit
 
</syntaxhighlight>
</lang>
 
=={{header|M4}}==
This code uses the "predicate" approach. A given x,y position is tested by a predicate as to whether it's on the curve or not and printed as a character or a space accordingly. The output goes row by row and column by column with no image storage or buffering.
 
<syntaxhighlight lang="text"># The macros which return a pair of values x,y expand to an unquoted 123,456
# which is suitable as arguments to a further macro. The quoting is slack
# because the values are always integers and so won't suffer unwanted macro
Line 3,110 ⟶ 4,939:
#
dragon_ascii(-6,5, dnl X range
-10,2) dnl Y range</langsyntaxhighlight>
 
;Output
Line 3,169 ⟶ 4,998:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Two functions: one that makes 2 lines from 1 line. And another that applies this function to all existing lines:
<langsyntaxhighlight Mathematicalang="mathematica">FoldOutLine[{a_,b_}]:={{a,#},{b,#}}&[a+0.5(b-a)+{{0.,0.5},{-0.5,0.}}.(b-a)]
NextStep[in_]:=Flatten[FoldOutLine/@in,1]
lines={{{0.,0.},{1.,0.}}};
Graphics[Line/@Nest[NextStep,lines,11]]</langsyntaxhighlight>
 
=={{header|Metafont}}==
Line 3,179 ⟶ 5,008:
The following code produces a single character font, 25 points wide and tall (0 points in depth), and store it in the position where one could expect to find the character D.
 
<langsyntaxhighlight lang="metafont">mode_setup;
dragoniter := 8;
beginchar("D", 25pt#, 25pt#, 0pt#);
Line 3,198 ⟶ 5,027:
draw for v:=1 step 2mstep until (2-2mstep): z[v] -- endfor z[2];
endchar;
end</langsyntaxhighlight>
 
The resulting character, magnified by 2, looks like:
 
<div style="text-align:center">[[Image:Dragon1.png]]</div>
 
=={{header|Nim}}==
{{trans|Go}}
{{libheader|imageman}}
The program is an adaptation of the second version of Go solution with some changes.
 
Rather than producing a big PPM file, we output a PNG file.
 
<syntaxhighlight lang="nim">import math
import imageman
 
const
## Separation of the two endpoints.
## Make this a power of 2 for prettier output.
Sep = 512
## Depth of recursion. Adjust as desired for different visual effects.
Depth = 18
 
S = sqrt(2.0) / 2
Sin = [float 0, S, 1, S, 0, -S, -1, -S]
Cos = [float 1, S, 0, -S, -1, -S, 0, S]
 
LineColor = ColorRGBU [byte 64, 192, 96]
Width = Sep * 11 div 6
Height = Sep * 4 div 3
 
Output = "dragon.png"
 
#---------------------------------------------------------------------------------------------------
 
func dragon(img: var Image; n, a, t: int; d, x, y: float) =
if n <= 1:
img.drawLine((x.toInt, y.toInt), ((x + d * Cos[a]).toInt, (y + d * Sin[a]).toInt), LineColor)
return
let d = d * S
let a1 = (a - t) and 7
let a2 = (a + t) and 7
img.dragon(n - 1, a1, 1, d, x, y)
img.dragon(n - 1, a2, -1, d, x + d * Cos[a1], y + d * Sin[a1])
 
#---------------------------------------------------------------------------------------------------
 
var image = initImage[ColorRGBU](Width, Height)
image.fill(ColorRGBU [byte 0, 0, 0])
image.dragon(Depth, 0, 1, Sep, Sep / 2, Sep * 5 / 6)
 
# Save into a PNG file.
image.savePNG(Output, compression = 9)</syntaxhighlight>
 
=={{header|OCaml}}==
{{libheader|Tk}}
Example solution, using an OCaml class and displaying the result in a Tk canvas, mostly inspired by the Tcl solution.
<langsyntaxhighlight lang="ocaml">(* This constant does not seem to be defined anywhere in the standard modules *)
let pi = acos (-1.0);
 
Line 3,284 ⟶ 5,161:
ignore (Canvas.create_line ~xys: dcc#get_coords c);
Tk.mainLoop ();
;;</langsyntaxhighlight>
=== A functional version ===
Here is another OCaml solution, in a functional rather than OO style:
<langsyntaxhighlight OCamllang="ocaml">let zig (x1,y1) (x2,y2) = (x1+x2+y1-y2)/2, (x2-x1+y1+y2)/2
let zag (x1,y1) (x2,y2) = (x1+x2-y1+y2)/2, (x1-x2+y1+y2)/2
 
Line 3,301 ⟶ 5,178:
let points = dragon p1 (zig p1 p2) p2 15 in
ignore (Canvas.create_line ~xys: points c);
Tk.mainLoop ()</langsyntaxhighlight>
producing:
<div>[[File:OCaml_Dragon-curve-example2.png‎]]</div>
Line 3,310 ⟶ 5,187:
Using the two sub-curves inward approach. The sub-curves are rotated and shifted explicitly. That could be combined into a <code>multmatrix()</code> each if desired. Lines segments are drawn as elongated cuboids.
 
<langsyntaxhighlight SCADlang="scad">level = 8;
linewidth = .1; // fraction of segment length
sqrt2 = pow(2, .5);
Line 3,328 ⟶ 5,205:
dragon(level);
}
</syntaxhighlight>
</lang>
 
=={{header|PARI/GP}}==
Line 3,335 ⟶ 5,212:
Using the "high level" <code>plothraw</code> with real and imaginary parts of vertex points as X and Y coordinates. Change <code>plothraw()</code> to <code>psplothraw()</code> to write a PostScript file "pari.ps" instead of drawing on-screen.
 
<langsyntaxhighlight lang="parigp">level = 13
p = [0, 1]; \\ complex number points, initially 0 to 1
 
Line 3,351 ⟶ 5,228:
p = concat(p, apply(z->(end - I*z), Vecrev(p[^-1]))))
 
plothraw(apply(real,p),apply(imag,p), 1); \\ flag=1 join points</langsyntaxhighlight>
 
===Version #2.===
Using the "low level" plotting functions to draw to a GUI window (X etc).
<langsyntaxhighlight lang="parigp">len=256;
 
bit_above_low_1(n) = bittest(n, valuation(n,2)+1);
Line 3,371 ⟶ 5,248:
for(i=1,len, plotrline(0,dx,dy); \
if(bit_above_low_1(i), turn_right(), turn_left()));
plotdraw([0,100,100]);</langsyntaxhighlight>
 
===Version #3.===
Line 3,382 ⟶ 5,259:
{{Works with|PARI/GP|2.7.4 and above}}
 
<langsyntaxhighlight lang="parigp">
\\ Dragon curve
\\ 4/8/16 aev
Line 3,403 ⟶ 5,280:
}
 
</langsyntaxhighlight>
 
{{Output}}
Line 3,426 ⟶ 5,303:
=={{header|Pascal}}==
using Compas (Pascal with Logo-expansion):
<langsyntaxhighlight lang="pascal">procedure dcr(step,dir:integer;length:real);
begin;
step:=step -1;
Line 3,468 ⟶ 5,345:
end;
end;
end;</langsyntaxhighlight>
main program:
<langsyntaxhighlight lang="pascal">begin
init;
penup;
Line 3,477 ⟶ 5,354:
dcr(step,direction,length);
close;
end.</langsyntaxhighlight>
 
 
=={{header|Perl}}==
As in the Perl 6Raku solution, we'll use a [[wp:L-System|Lindenmayer system]] and draw the dragon in [[wp:SVG|SVG]].
<langsyntaxhighlight lang="perl">use SVG;
use List::Util qw(max min);
 
Line 3,521 ⟶ 5,399:
open $fh, '>', 'dragon_curve.svg';
print $fh $svg->xmlify(-namespace=>'svg');
close $fh;</langsyntaxhighlight>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/dragon_curve.svg Dragon curve] (offsite image)
 
=={{header|Perl 6}}==
We'll use a L-System role, and draw the dragon in SVG.
<lang perl6>use SVG;
 
role Lindenmayer {
has %.rules;
method succ {
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
}
}
 
my $dragon = "FX" but Lindenmayer( { X => 'X+YF+', Y => '-FX-Y' } );
 
$dragon++ xx ^15;
 
my @points = 215, 350;
 
for $dragon.comb {
state ($x, $y) = @points[0,1];
state $d = 2 + 0i;
if /'F'/ { @points.append: ($x += $d.re).round(.1), ($y += $d.im).round(.1) }
elsif /< + - >/ { $d *= "{$_}1i" }
}
 
say SVG.serialize(
svg => [
:600width, :450height, :style<stroke:rgb(0,0,255)>,
:rect[:width<100%>, :height<100%>, :fill<white>],
:polyline[ :points(@points.join: ','), :fill<white> ],
],
);</lang>
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/dragoncurve.htm here].
Changing the colour and depth give some mildly interesting results.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>--
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\DragonCurve.exw
-- demo\rosetta\DragonCurve.exw
--
-- ============================
include pGUI.e
--</span>
 
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Ihandle dlg, canvas
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
cdCanvas cddbuffer, cdcanvas
 
integer colour = 0
 
procedure Dragon(integer depth, atom x1, y1, x2, y2)
depth -= 1
if depth<=0 then
cdCanvasSetForeground(cddbuffer, colour)
cdCanvasLine(cddbuffer, x1, y1, x2, y2)
-- (some interesting colour patterns emerge)
colour += 2
-- colour += 2000
-- colour += #100
else
atom dx = x2-x1, dy = y2-y1,
nx = x1+(dx-dy)/2,
ny = y1+(dx+dy)/2
Dragon(depth,x1,y1,nx,ny)
Dragon(depth,x2,y2,nx,ny)
end if
end procedure
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
cdCanvasActivate(cddbuffer)
cdCanvasClear(cddbuffer)
<span style="color: #004080;">integer</span> <span style="color: #000000;">colour</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
-- (note: depths over 21 take a long time to draw,
-- depths <= 16 look a little washed out)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Dragon</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">)</span>
Dragon(17,100,100,100+256,100)
<span style="color: #000000;">depth</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
cdCanvasFlush(cddbuffer)
<span style="color: #008080;">if</span> <span style="color: #000000;">depth</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
return IUP_DEFAULT
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">colour</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #7060A8;">cdCanvasLine</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000080;font-style:italic;">-- (some interesting colour patterns emerge)</span>
function map_cb(Ihandle ih)
<span style="color: #000000;">colour</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">2</span>
cdcanvas = cdCreateCanvas(CD_IUP, ih)
<span style="color: #000080;font-style:italic;">-- colour += 2000
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
-- colour += #100</span>
cdCanvasSetBackground(cddbuffer, CD_PARCHMENT)
<span style="color: #008080;">else</span>
return IUP_DEFAULT
<span style="color: #004080;">atom</span> <span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span>
end function
<span style="color: #000000;">nx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span>
 
<span style="color: #000000;">ny</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
function esc_close(Ihandle /*ih*/, atom c)
<span style="color: #000000;">Dragon</span><span style="color: #0000FF;">(</span><span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">)</span>
if c=K_ESC then return IUP_CLOSE end if
<span style="color: #000000;">Dragon</span><span style="color: #0000FF;">(</span><span style="color: #000000;">depth</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">)</span>
return IUP_CONTINUE
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
procedure main()
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*posx*/</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*posy*/</span><span style="color: #0000FF;">)</span>
IupOpen()
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
 
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
canvas = IupCanvas(NULL)
<span style="color: #000080;font-style:italic;">-- (note: depths over 21 take a long time to draw,
IupSetAttribute(canvas, "RASTERSIZE", "420x290")
-- depths &lt;= 16 look a little washed out)</span>
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
<span style="color: #000000;">Dragon</span><span style="color: #0000FF;">(</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">+</span><span style="color: #000000;">256</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)</span>
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
dlg = IupDialog(canvas,"RESIZE=NO")
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
IupSetAttribute(dlg, "TITLE", "Dragon Curve")
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
IupShow(dlg)
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span>
IupMainLoop()
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_PARCHMENT</span><span style="color: #0000FF;">)</span>
IupClose()
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
main()</lang>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"420x290"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RESIZE=NO"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Dragon Curve"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
{{trans|Forth}}
This uses the 'brez' line drawing function from [[Bitmap/Bresenham's line algorithm#PicoLisp]].
<langsyntaxhighlight PicoLisplang="picolisp"># Need some turtle graphics
(load "@lib/math.l")
 
Line 3,670 ⟶ 5,518:
(prinl "P1")
(prinl 300 " " 200)
(mapc prinl Img) ) )</langsyntaxhighlight>
 
=={{header|PL/I}}==
Line 3,680 ⟶ 5,528:
 
A restriction of the pl/i compiler in the 1980s was that array indices could not exceed 32767, thus the escalation to a two-dimensional array, as in <code>DECLARE FOLD(0:31,0:32767) BOOLEAN; /*Oh for (0:1000000) or so..*/</code> This made the array indexing rather messy.
<syntaxhighlight lang="pli">
<lang PLI>
* PROCESS GONUMBER, MARGINS(1,72), NOINTERRUPT, MACRO;
TEST:PROCEDURE OPTIONS(MAIN);
Line 3,918 ⟶ 5,766:
CALL PLOT(0,0,-3); CALL PLOT(0,0,999);
END TEST;
</syntaxhighlight>
</lang>
 
=={{header|PostScript}}==
<langsyntaxhighlight lang="postscript">%!PS
%%BoundingBox: 0 0 550 400
/ifpendown false def
Line 3,964 ⟶ 5,812:
% 0 0 moveto 550 0 rlineto 0 400 rlineto -550 0 rlineto closepath stroke
showpage
%%END</langsyntaxhighlight>
 
Or (almost) verbatim string rewrite: (this is a 20 page document, and don't try to print it,
or you might have a very angry printer).
<langsyntaxhighlight lang="postscript">%!PS-Adobe-3.0
%%BoundingBox 0 0 300 300
 
Line 3,989 ⟶ 5,837:
1 1 20 { dragon showpage } for
 
%%EOF</langsyntaxhighlight>
;See also:
* [http://www.cs.unh.edu/~charpov/Programming/L-systems/ L-systems in Postscript]
Line 3,995 ⟶ 5,843:
=={{header|POV-Ray}}==
Example code recursive and iterative can be found at [http://aesculier.fr/fichiersPovray/dragon/dragon.html Courbe du Dragon].
 
=={{header|PowerShell}}==
==={{header|WinForms}}===
{{trans|Logo}}
{{libheader|turtle}}
<syntaxhighlight lang="powershell"># handy constants with script-wide scope
[Single]$script:QUARTER_PI=0.7853982
[Single]$script:HALF_PI=1.570796
 
# leverage GDI (Forms and Drawing)
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
$script:TurtlePen = New-Object Drawing.Pen darkGreen
$script:Form = New-Object Windows.Forms.Form
$script:Canvas = $Form.CreateGraphics()
 
# implement a turtle graphics model
Class Turtle { # relies on the script-scoped $TurtlePen and $Canvas
# member properties for turtle's position and orientation
[Single]$TurtleX
[Single]$TurtleY
[Single]$TurtleAngle
 
# constructors
Turtle() {
$this.TurtleX, $this.TurtleY = 44.0, 88.0
$this.TurtleAngle = 0.0
}
Turtle([Single]$InitX, [Single]$InitY, [Single]$InitAngle) {
$this.TurtleX, $this.TurtleY = $InitX, $InitY
$this.TurtleAngle = $InitAngle
}
 
# methods for turning and drawing
[Void]Turn([Single]$Angle) { # $Angle measured in radians
$this.TurtleAngle += $Angle # use positive $Angle for right turn, negative for left turn
}
[Void]Forward([Single]$Distance) {
# draw line segment
$TargetX = $this.TurtleX + $Distance * [Math]::Cos($this.TurtleAngle)
$TargetY = $this.TurtleY + $Distance * [Math]::Sin($this.TurtleAngle)
$script:Canvas.DrawLine($script:TurtlePen, $this.TurtleX, $this.TurtleY, $TargetX, $TargetY)
# relocate turtle to other end of segment
$this.TurtleX = $TargetX
$this.TurtleY = $TargetY
}
} # end of Turtle class definition
 
# Implement dragon curve drawing methods in a subclass that inherits Turtle
Class DragonTurtle : Turtle {
 
# DCL: recursive dragon curve, starting with left turns
[Void]DCL([Byte]$Step, [Single]$Length) {
$AdjustedStep = $Step - 1
$AdjustedLength = $Length / [Math]::Sqrt(2.0)
 
$this.Turn(-$script:QUARTER_PI)
if ($AdjustedStep -gt 0) {
$this.DCR($AdjustedStep, $AdjustedLength)
} else {
$this.Forward($AdjustedLength)
}
$this.Turn($script:HALF_PI)
if ($AdjustedStep -gt 0) {
$this.DCL($AdjustedStep, $AdjustedLength)
} else {
$this.Forward($AdjustedLength)
}
$this.Turn(-$script:QUARTER_PI)
}
 
# DCR: recursive dragon curve, starting with right turns
[Void]DCR([Byte]$Step, [Single]$Length) {
$AdjustedStep = $Step - 1
$AdjustedLength = $Length / [Math]::Sqrt(2.0)
 
$this.Turn($script:QUARTER_PI)
if ($AdjustedStep -gt 0) {
$this.DCR($AdjustedStep, $AdjustedLength)
} else {
$this.Forward($AdjustedLength)
}
$this.Turn(-$script:HALF_PI)
if ($AdjustedStep -gt 0) {
$this.DCL($AdjustedStep, $AdjustedLength)
} else {
$this.Forward($AdjustedLength)
}
$this.Turn($script:QUARTER_PI)
}
} # end of DragonTurtle subclass definition
 
# prepare anonymous dragon-curve painting function for WinForms dialog
$Form.add_paint({
[DragonTurtle]$Dragon = [DragonTurtle]::new()
$Dragon.DCR(14,128)
})
 
# display the GDI Form window, which triggers its prepared anonymous drawing function
$Form.ShowDialog()
</syntaxhighlight>
 
=={{header|Processing}}==
<syntaxhighlight lang="java">float l = 3;
int ints = 13;
 
void setup() {
size(700, 600);
background(0, 0, 255);
translate(150, 100);
stroke(255);
turn_left(l, ints);
turn_right(l, ints);
}
 
void turn_right(float l, int ints) {
if (ints == 0) {
line(0, 0, 0, -l);
translate(0, -l);
} else {
turn_left(l, ints-1);
rotate(radians(90));
turn_right(l, ints-1);
}
}
 
void turn_left(float l, int ints) {
if (ints == 0) {
line(0, 0, 0, -l);
translate(0, -l);
} else {
turn_left(l, ints-1);
rotate(radians(-90));
turn_right(l, ints-1);
}
}</syntaxhighlight>'''The sketch can be run online''' :<BR> [https://www.openprocessing.org/sketch/847651 here.]
 
==={{header|Processing Python mode}}===
<syntaxhighlight lang="python">l = 3
ints = 13
 
def setup():
size(700, 600)
background(0, 0, 255)
translate(150, 100)
stroke(255)
turn_left(l, ints)
turn_right(l, ints)
 
def turn_right(l, ints):
if ints == 0:
line(0, 0, 0, -l)
translate(0, -l)
else:
turn_left(l, ints - 1)
rotate(radians(90))
turn_right(l, ints - 1)
def turn_left(l, ints):
if ints == 0:
line(0, 0, 0, -l)
translate(0, -l)
else:
turn_left(l, ints - 1)
rotate(radians(-90))
turn_right(l, ints - 1)</syntaxhighlight>
 
=={{header|Prolog}}==
Works with SWI-Prolog which has a Graphic interface XPCE.<BR>
DCG are used to compute the list of "turns" of the Dragon Curve and the list of points.
<langsyntaxhighlight Prologlang="prolog">dragonCurve(N) :-
dcg_dg(N, [left], DCL, []),
Side = 4,
Line 4,058 ⟶ 6,072:
 
inverse(right) -->
[left].</langsyntaxhighlight>
Output :
<pre>1 ?- dragonCurve(13).
true </pre>[[File : Prolog-DragonCurve.jpg]]
 
=={{header|PureBasic}}==
<lang PureBasic>#SqRt2 = 1.4142136
#SizeH = 800: #SizeV = 550
Global angle.d, px, py, imageNum
 
Procedure turn(degrees.d)
angle + degrees * #PI / 180
EndProcedure
 
Procedure forward(length.d)
Protected w = Cos(angle) * length
Protected h = Sin(angle) * length
LineXY(px, py, px + w, py + h, RGB(255,255,255))
px + w: py + h
EndProcedure
 
Procedure dragon(length.d, split, d.d)
If split = 0
forward(length)
Else
turn(d * 45)
dragon(length / #SqRt2, split - 1, 1)
turn(-d * 90)
dragon(length / #SqRt2, split - 1, -1)
turn(d * 45)
EndIf
EndProcedure
 
OpenWindow(0, 0, 0, #SizeH, #SizeV, "DragonCurve", #PB_Window_SystemMenu)
imageNum = CreateImage(#PB_Any, #SizeH, #SizeV, 32)
ImageGadget(0, 0, 0, 0, 0, ImageID(imageNum))
angle = 0: px = 185: py = 190
If StartDrawing(ImageOutput(imageNum))
dragon(400, 15, 1)
StopDrawing()
SetGadgetState(0, ImageID(imageNum))
EndIf
 
Repeat: Until WaitWindowEvent(10) = #PB_Event_CloseWindow</lang>
 
=={{header|Python}}==
{{trans|Logo}}
{{libheader|turtle}}
<langsyntaxhighlight lang="python">from turtle import *
 
def dragon(step, length):
Line 4,143 ⟶ 6,116:
right(90)
forward(length)
left(45)</langsyntaxhighlight>
A more pythonic version:
<langsyntaxhighlight lang="python">from turtle import right, left, forward, speed, exitonclick, hideturtle
 
def dragon(level=4, size=200, zig=right, zag=left):
Line 4,162 ⟶ 6,135:
hideturtle()
dragon(6)
exitonclick() # click to exit</langsyntaxhighlight>
Other version:
<langsyntaxhighlight lang="python">from turtle import right, left, forward, speed, exitonclick, hideturtle
 
def dragon(level=4, size=200, direction=45):
Line 4,179 ⟶ 6,152:
hideturtle()
dragon(6)
exitonclick() # click to exit</langsyntaxhighlight>
 
=={{header|Quackery}}==
<syntaxhighlight lang="quackery"> [ $ "turtleduck.qky" loadfile ] now!
 
[ 2 *
2dup turn
4 1 walk
turn ] is corner ( n/d --> )
 
forward is right ( n --> )
 
forward is left ( n --> )
 
[ dup 0 = iff
[ drop 8 1 walk ] done
1 - dup
left
1 4 corner
right ] resolves right ( n --> )
 
[ dup 0 = iff
[ drop 8 1 walk ] done
1 - dup
left
-1 4 corner
right ] resolves left ( n --> )
turtle
20 frames
-260 1 fly
3 4 turn
100 1 fly
5 8 turn
11 left
1 frames</syntaxhighlight>
 
{{output}}
 
[[File:Quackery dragon curve.png|thumb|center]]
 
=={{header|R}}==
===Version #1.===
<syntaxhighlight lang="r">
<lang R>
Dragon<-function(Iters){
Rotation<-matrix(c(0,-1,1,0),ncol=2,byrow=T) ########Rotation multiplication matrix
Line 4,216 ⟶ 6,228:
segments(Iteration[[i]][s,1], Iteration[[i]][s,2], Iteration[[i]][s,3], Iteration[[i]][s,4], col= 'red')
}}#########################################################################
</syntaxhighlight>
</lang>
[https://commons.wikimedia.org/wiki/File:Dragon_Curve_16_Iterations_R_programming_language.png#mediaviewer/File:Dragon_Curve_16_Iterations_R_programming_language.png]
 
Line 4,228 ⟶ 6,240:
[[File:DCR13.png|200px|right|thumb|Output DCR13.png]]
[[File:DCR16.png|200px|right|thumb|Output DCR16.png]]
<syntaxhighlight lang="r">
<lang r>
# Generate and plot Dragon curve.
# translation of JavaScript v.#2: http://rosettacode.org/wiki/Dragon_curve#JavaScript
Line 4,262 ⟶ 6,274:
##gpDragonCurve(15, "darkgreen", "", 10, 2, -450, -500)
gpDragonCurve(16, "darkgreen", "", 10, 3, -1050, -500)
</syntaxhighlight>
</lang>
 
{{Output}}
Line 4,283 ⟶ 6,295:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket
 
(require plot)
Line 4,320 ⟶ 6,332:
new-pos
(cons new-pos trail))))])
(plot-file (lines trail) "dragon.png" 'png))</langsyntaxhighlight>
[[Image:Racket_Dragon_curve.png]]
 
=={{header|Raku}}==
(formerly Perl 6)
We'll use a L-System role, and draw the dragon in SVG.
<syntaxhighlight lang="raku" line>use SVG;
 
role Lindenmayer {
=={{header|RapidQ}}==
has %.rules;
{{trans|BASIC}}
method succ {
This implementation displays the Dragon Curve fractal in a [[GUI]] window.
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
<lang rapidq>DIM angle AS Double
}
DIM x AS Double, y AS Double
}
DECLARE SUB PaintCanvas
 
my $dragon = "FX" but Lindenmayer( { X => 'X+YF+', Y => '-FX-Y' } );
CREATE form AS QForm
Width = 800
Height = 600
CREATE canvas AS QCanvas
Height = form.ClientHeight
Width = form.ClientWidth
OnPaint = PaintCanvas
END CREATE
END CREATE
 
$dragon++ xx ^15;
SUB turn (degrees AS Double)
angle = angle + degrees*3.14159265/180
END SUB
SUB forward (length AS Double)
x2 = x + cos(angle)*length
y2 = y + sin(angle)*length
canvas.Line(x, y, x2, y2, &Haaffff)
x = x2: y = y2
END SUB
 
my @points = 215, 350;
SUB dragon (length AS Double, split AS Integer, d AS Double)
IF split=0 THEN
forward length
ELSE
turn d*45
dragon length/1.4142136, split-1, 1
turn -d*90
dragon length/1.4142136, split-1, -1
turn d*45
END IF
END SUB
 
for $dragon.comb {
SUB PaintCanvas
state ($x, $y) = @points[0,1];
canvas.FillRect(0, 0, canvas.Width, canvas.Height, &H102800)
xstate = 220: y$d = 220:2 angle =+ 00i;
if /'F'/ { @points.append: ($x += $d.re).round(.1), ($y += $d.im).round(.1) }
dragon 384, 12, 1
elsif /< + - >/ { $d *= "{$_}1i" }
END SUB
}
 
say SVG.serialize(
form.ShowModal</lang>
svg => [
:600width, :450height, :style<stroke:rgb(0,0,255)>,
:rect[:width<100%>, :height<100%>, :fill<white>],
:polyline[ :points(@points.join: ','), :fill<white> ],
],
);</syntaxhighlight>
 
=={{header|REXX}}==
Line 4,381 ⟶ 6,377:
 
This, in effect, allows the dragon curve to be plotted/displayed with a different (starting) orientation.
<langsyntaxhighlight lang="rexx">/*REXX program creates & draws an ASCII Dragon Curve (or Harter-Heighway dragon curve).*/
d.= 1; d.L= -d.; @.= ' '; x= 0; x2= x; y= 0; y2= y; z= d.; @.x.y= "∙"
plot_pts = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZΘ' /*plot chars*/
minXloX= 0; maxXhiX= 0; minYloY= 0; maxYhiY= 0 /*assign various constants & variables.*/
parse arg # p c . /*#: number of iterations; P=init dir.*/
if #=='' | #=="," then #=11 11 /*Not specified? Then use the default.*/
if p=='' | p=="," then p= 'north'; upper p /* " " " " " " */
if c=='' then c=plot_pts plot_pts /* " " " " " " */
if length(c)==2 then c= x2c(c) /*was a hexadecimal code specified? */
if length(c)==3 then c= d2c(c) /* " " decimal " " */
p= translate( left(p, 1), 0123, 'NESW'); $= /*get the orientation for dragon curve.*/
$= /*initialize the dragon curve to a null*/
do #; $=$'R'reverse(translate($,"RL",'LR')) /*create the start of a dragon curve. */
do # end /*#*/ /*appendcreate char,the flip,start of anda thendragon reversecurve. */
$= $'R'reverse( translate($, "RL", 'LR') ) /* [↓] createappend the rest of dragon curve. */
end /*#*/ /* [↑] append char, flip, and reverse.*/
do j=1 for length($); _=substr($,j,1) /*get next cardinal direction for curve*/
 
p= (p+d._)//4; if p<0 then p=p+4 /*move dragon curve in a new direction.*/
ifdo pj==01 thenfor dolength($); y=y+1; y2_=y+1; substr($, j, end 1) /*curveget isnext goingcardinal direction eastfor cartologically.curve*/
if p==1 (p then do; x=x+1; d._) x2=x+1;// 4 end /* " " south " /*move dragon curve in a new direction.*/
if p==2< 0 then do; yp=y-1; p y2=y-1;+ 4 end /* " " west /*Negative? Then use a " new direction. */
if p==30 then do; y= y + x=x-1; x2y2=x-1; y + 1; end /*curve is " " north " going east cartologically.*/
if j>2**zp==1 then zdo; x=z x + 1; x2= x + 1; end /* " " south /*identify a part of curve being" built.*/
if p==2 then do; y= y - 1; y2= y - 1; end /* " " west " */
!=substr(c,z,1); if !==' ' then !=right(c,1) /*choose plot point character (glyph). */
@.x.yif p=!;=3 then @.x2.y2do; x=! x - 1; x2= x - 1; end /* " " north /*draw part of the dragon" curve. */
if j>2**z then z= z + 1 /*identify a part of curve being built.*/
minX=min(minX,x,x2); maxX=max(maxX,x,x2); x=x2 /*define the min & max X graph limits*/
minY!=min substr(minYc,y,y2); maxY=max(maxYz,y,y2 1); y=y2 /* " " " " " Y " " /*choose plot point character (glyph). */
end /*j*/ if !==' ' then != right(c, 1) /*Plot [↑] processpoint alla ofblank? $Then use chara string.glyph*/
@.x.y= !; do r @.x2.y2=minX ! to maxX; a= /*nullifydraw thepart lineof thatthe will bedragon drawncurve. */
loX= min(loX,x,x2); hiX= max(hiX,x,x2); x= x2 /*define the min & max X graph limits*/
do c=minY to maxY; a=a || @.r.c /*create a line (row) of curve points. */
loY= min(loY,y,y2); hiY= max(hiY,y,y2); y= y2 /* " " " " " Y " " */
end /*j*/ /* [↑] process all of $ char string.*/
do r=loX to hiX; a= /*nullify the line that will be drawn. */
do c=loY to hiY; a= a || @.r.c /*create a line (row) of curve points. */
end /*c*/ /* [↑] append a single column of a row.*/
if a\=='' then say strip(a, "T") /*display a line (row) of curve points.*/
end /*r*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
Choosing a &nbsp; ''high visibility'' &nbsp; glyph can really help make the dragon much more viewable; &nbsp; the
<br>solid fill ASCII character &nbsp; (█ &nbsp; or &nbsp; hexadecimal &nbsp; '''db''' &nbsp; in code page 437) &nbsp; is quite good for this.
Line 4,551 ⟶ 6,551:
=={{header|Ruby}}==
{{libheader|Shoes}}
<langsyntaxhighlight lang="ruby">Point = Struct.new(:x, :y)
Line = Struct.new(:start, :stop)
 
Line 4,582 ⟶ 6,582:
end
end
end</langsyntaxhighlight>
 
{{libheader|RubyGems}}
=={{header|Run BASIC}}==
{{libheader|JRubyArt}}
<lang runbasic>graphic #g, 600,600
<syntaxhighlight lang="ruby">LEN = 3
RL$ = "R"
loc GEN = 9014
attr_reader :angle
pass = 0
 
def setup
[loop]
sketch_title 'Heighway Dragon'
#g "cls ; home ; north ; down ; fill black"
background(0, 0, 255)
for i =1 to len(RL$)
translate(170, 170)
v = 255 * i /len(RL$)
stroke(255)
#g "color "; v; " 120 "; 255 -v
@angle = 90.radians
#g "go "; loc
turn_left(GEN)
if mid$(RL$,i,1) ="R" then #g "turn 90" else #g "turn -90"
end
next i
 
def draw_line
#g "color 255 120 0"
line(0, 0, 0, -LEN)
#g "go "; loc
translate(0, -LEN)
LR$ =""
end
for i =len( RL$) to 1 step -1
if mid$( RL$, i, 1) ="R" then LR$ =LR$ +"L" else LR$ =LR$ +"R"
next i
 
def turn_right(gen)
RL$ = RL$ + "R" + LR$
return draw_line if gen.zero?
loc = loc / 1.35
pass = pass + 1
render #g
input xxx
cls
 
turn_left(gen - 1)
if pass < 16 then goto [loop]
rotate(angle)
end</lang>
turn_right(gen - 1)
<div>[[File:DragonCurveRunBasic.png‎]]</div>
end
 
def turn_left(gen)
return draw_line if gen.zero?
 
turn_left(gen - 1)
rotate(-angle)
turn_right(gen - 1)
end
 
def settings
size(700, 600)
end
</syntaxhighlight>
 
{{libheader|RubyGems}}
{{libheader|JRubyArt}}
{{libheader|cf3ruby}}
Context Free Art version
<syntaxhighlight lang="ruby">require 'cf3'
 
INV_SQRT = 1 / Math.sqrt(2)
 
def setup_the_dragon
@dragon = ContextFree.define do
shape :start do
dragon alpha: 1
end
 
shape :dragon do
square hue: 0, brightness: 0, saturation: 1, alpha: 0.02
split do
dragon size: INV_SQRT, rotation: -45, x: 0.25, y: 0.25
rewind
dragon size: INV_SQRT, rotation: 135, x: 0.25, y: 0.25
rewind
end
end
end
end
 
def settings
size 800, 500
end
 
def setup
sketch_title 'Heighway Dragon'
setup_the_dragon
draw_it
end
 
def draw_it
background 255
@dragon.render :start, size: width * 0.8, stop_size: 2,
start_x: width / 3, start_y: height / 3.5
end
</syntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use ggez::{
conf::{WindowMode, WindowSetup},
error::GameResult,
event,
graphics::{clear, draw, present, Color, MeshBuilder},
nalgebra::Point2,
Context,
};
use std::time::Duration;
 
// L-System to create the sequence needed for a Dragon Curve.
// This function creates the next generation given the current one
// L-System from https://www.cs.unm.edu/~joel/PaperFoldingFractal/L-system-rules.html
//
fn l_system_next_generation(current_generation: &str) -> String {
let f_rule = "f-h";
let h_rule = "f+h";
let mut next_gen = String::new();
for char in current_generation.chars() {
match char {
'f' => next_gen.push_str(f_rule),
'h' => next_gen.push_str(h_rule),
'-' | '+' => next_gen.push(char),
_ => panic!("Unknown char {}", char),
}
}
next_gen
}
 
// The rest of the code is for drawing the output and is specific to using the
// ggez 2d game library: https://ggez.rs/
 
const WINDOW_WIDTH: f32 = 700.0;
const WINDOW_HEIGHT: f32 = 700.0;
const START_X: f32 = WINDOW_WIDTH / 6.0;
const START_Y: f32 = WINDOW_HEIGHT / 6.0;
const MAX_DEPTH: i32 = 15;
const LINE_LENGTH: f32 = 20.0;
 
struct MainState {
start_gen: String,
next_gen: String,
line_length: f32,
max_depth: i32,
current_depth: i32,
}
 
impl MainState {
fn new() -> GameResult<MainState> {
let start_gen = "f";
let next_gen = String::new();
let line_length = LINE_LENGTH;
let max_depth = MAX_DEPTH;
let current_depth = 0;
Ok(MainState {
start_gen: start_gen.to_string(),
next_gen,
line_length,
max_depth,
current_depth,
})
}
}
 
impl event::EventHandler for MainState {
// In each repetition of the event loop a new generation of the L-System
// is generated and drawn, until the maximum depth is reached.
// Each time the line length is reduced so that the overall dragon curve
// can be seen in the window as it spirals and gets bigger.
// The update sleeps for 0.5 seconds just so that its pogression can be watched.
//
fn update(&mut self, _ctx: &mut Context) -> GameResult {
if self.current_depth < self.max_depth {
self.next_gen = l_system_next_generation(&self.start_gen);
self.start_gen = self.next_gen.clone();
self.line_length -= (self.line_length / self.max_depth as f32) * 1.9;
self.current_depth += 1;
}
ggez::timer::sleep(Duration::from_millis(500));
Ok(())
}
 
fn draw(&mut self, ctx: &mut Context) -> GameResult {
let grey = Color::from_rgb(77, 77, 77);
let blue = Color::from_rgb(51, 153, 255);
let initial_point_blue = Point2::new(START_X, START_Y);
clear(ctx, grey);
draw_lines(
&self.next_gen,
ctx,
self.line_length,
blue,
initial_point_blue,
)?;
present(ctx)?;
Ok(())
}
}
 
fn next_point(current_point: Point2<f32>, heading: f32, line_length: f32) -> Point2<f32> {
let next_point = (
(current_point.x + (line_length * heading.to_radians().cos().trunc() as f32)),
(current_point.y + (line_length * heading.to_radians().sin().trunc() as f32)),
);
Point2::new(next_point.0, next_point.1)
}
 
fn draw_lines(
instructions: &str,
ctx: &mut Context,
line_length: f32,
colour: Color,
initial_point: Point2<f32>,
) -> GameResult {
let line_width = 2.0;
let mut heading = 0.0;
let turn_angle = 90.0;
let mut start_point = initial_point;
let mut line_builder = MeshBuilder::new();
for char in instructions.chars() {
let end_point = next_point(start_point, heading, line_length);
match char {
'f' | 'h' => {
line_builder.line(&[start_point, end_point], line_width, colour)?;
start_point = end_point;
}
'+' => heading += turn_angle,
'-' => heading -= turn_angle,
_ => panic!("Unknown char {}", char),
}
}
let lines = line_builder.build(ctx)?;
draw(ctx, &lines, (initial_point,))?;
Ok(())
}
 
fn main() -> GameResult {
let cb = ggez::ContextBuilder::new("dragon curve", "huw")
.window_setup(WindowSetup::default().title("Dragon curve"))
.window_mode(WindowMode::default().dimensions(WINDOW_WIDTH, WINDOW_HEIGHT));
let (ctx, event_loop) = &mut cb.build()?;
let state = &mut MainState::new()?;
event::run(ctx, event_loop, state)
}
</syntaxhighlight>
<div>[[File:dragon_curve_rust.gif]]</div>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">import javax.swing.JFrame
import java.awt.Graphics
 
Line 4,668 ⟶ 6,868:
object DragonCurve extends App {
new DragonCurve(14).setVisible(true);
}</langsyntaxhighlight>
 
=={{header|Scilab}}==
It uses complex numbers and treats them as vectors to perform rotations of the edges of the curve around one of its ends. The output is a shown in a graphic window.
<syntaxhighlight lang="text">n_folds=10
 
folds=[];
Line 4,707 ⟶ 6,907:
 
set(gca(),"isoview","on");
set(gca(),"axes_visible",["off","off","off"]);</langsyntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
include "math.s7i";
Line 4,757 ⟶ 6,957:
dragon(768.0, 14, 1);
ignore(getc(KEYBOARD));
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/graphic.htm#dragon_curve]
Line 4,763 ⟶ 6,963:
=={{header|SequenceL}}==
'''Tail-Recursive SequenceL Code:'''<br>
<langsyntaxhighlight lang="sequencel">import <Utilities/Math.sl>;
import <Utilities/Conversion.sl>;
 
Line 4,800 ⟶ 7,000:
result when steps <= 0
else
run(steps - 1, next);</langsyntaxhighlight>
 
'''C++ Driver Code:'''<br>
{{libheader|CImg}}
<langsyntaxhighlight lang="c">#include <iostream>
#include <vector>
#include "SL_Generated.h"
Line 4,877 ⟶ 7,077:
sl_done();
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 4,883 ⟶ 7,083:
 
=={{header|Sidef}}==
Uses the '''LSystem()''' class from [https://rosettacode.org/wiki/Hilbert_curve#Sidef Hilbert curve].
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">definevar halfpirules = Num.pi/2Hash(
x => 'x+yF+',
y => '-Fx-y',
)
 
var lsys = LSystem(
# Computing the dragon with a L-System
width: 600,
var dragon = 'FX'
height: 600,
{
dragon.gsub!('X', 'x+yF+')
dragon.gsub!('Y', '-Fx-y')
dragon.tr!('xy', 'XY')
} * 10
 
xoff: -430,
# Drawing the dragon in SVG
yoff: -380,
var (x, y) = (100, 100)
var theta = 0
var r = 2
 
len: 8,
print <<'EOT'
angle: 90,
<?xml version='1.0' encoding='utf-8' standalone='no'?>
color: 'dark green',
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'
)
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg width='100%' height='100%' version='1.1'
xmlns='http://www.w3.org/2000/svg'>
EOT
 
dragon.each { |c|
given(c) {
when ('F') {
printf("<line x1='%.0f' y1='%.0f' ", x, y)
printf("x2='%.0f' ", x += r*cos(theta))
printf("y2='%.0f' ", y += r*sin(theta))
printf("style='stroke:rgb(0,0,0);stroke-width:1'/>\n")
}
when ('+') { theta += halfpi }
when ('-') { theta -= halfpi }
}
}
 
lsys.execute('Fx', 11, "dragon_curve.png", rules)</syntaxhighlight>
print '</svg>'</lang>
Output image: [https://github.com/trizen/rc/blob/master/img/dragon_curve-sidef.png Dragon curve]
Generates a SVG image to the standard output.
 
=={{header|Smalltalk}}==
Line 4,934 ⟶ 7,115:
=={{header|SPL}}==
Animation of dragon curve.
<langsyntaxhighlight lang="spl">levels = 16
level = 0
step = 1
Line 4,971 ⟶ 7,152:
<
#.scr()
.</langsyntaxhighlight>
 
=={{header|SVG}}==
Line 4,984 ⟶ 7,165:
 
<div style="clear: right;"></div>
<langsyntaxhighlight lang="xml"><?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
Line 5,043 ⟶ 7,224:
</g>
 
</svg></langsyntaxhighlight>
 
=={{header|Tcl}}==
{{works with|Tcl|8.5}}
{{libheader|Tk}}
<langsyntaxhighlight lang="tcl">package require Tk
 
set pi [expr acos(-1)]
Line 5,089 ⟶ 7,270:
.c create line {0 0 0 0} -tag dragon
dragon 400 17
.c coords dragon $coords</langsyntaxhighlight>
 
See also the Tcl/Tk wiki [http://wiki.tcl.tk/3349 Dragon Curves] and [http://wiki.tcl.tk/10745 Recursive curves] pages.
Line 5,096 ⟶ 7,277:
===PGF===
{{libheader|PGF}}
The [http://sourceforge.net/projects/pgf/ PGF] package includes a "lindenmayersystems" library. A dragon can be made with the "F-S" rule by defining S as a second drawing symbol. So, for [[plainTeX]],
 
A dragon can be made with the "F-S" rule by defining S as a second drawing symbol.
<lang TeX>\input tikz.tex
 
So, for [[plainTeX]],
 
<syntaxhighlight lang="tex">\input tikz.tex
\usetikzlibrary{lindenmayersystems}
 
\pgfdeclarelindenmayersystem{Dragon curve}{
\symbol{S}{\pgflsystemdrawforward}
\rule{F -> F+S}
\rule{S -> F-S}
}
\tikzpicture
\draw
[lindenmayer system={Dragon curve, step=10pt, axiom=F, order=8}]
lindenmayer system;
\endtikzpicture
\bye</syntaxhighlight>
\bye
</lang>
 
=={{header|LaTeX}}==
Or fixed-direction variant to stay horizontal, this time for [[LaTeX]],
 
<langsyntaxhighlight TeXlang="latex">\documentclass{articleminimal}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\begin{document}
 
\pgfdeclarelindenmayersystem{Dragon curve}{
\symbol{S}{\pgflsystemdrawforward}
\rule{F -> -F++S-}
\rule{S -> +F--S+}
}
 
\foreach \i in {1,...,8} {
\hbox{
order=\i
\hspace{.5em}
\begin{tikzpicture}[baseline=0pt]
\draw
[lindenmayer system={Dragon curve, step=10pt,angle=45, axiom=F, order=\i}]
lindenmayer system;
\end{tikzpicture}
\hspace{1em}
}
\vspace{.5ex}
}
\endbegin{document}
\end{document}</syntaxhighlight>
</lang>
 
=={{header|TI-89 BASIC}}==
{{trans|SVG}}
<lang ti89b>Define dragon = (iter, xform)
Prgm
Local a,b
If iter > 0 Then
dragon(iter-1, xform*[[.5,.5,0][–.5,.5,0][0,0,1]])
dragon(iter-1, xform*[[–.5,.5,0][–.5,–.5,1][0,0,1]])
Else
xform*[0;0;1]→a
xform*[0;1;1]→b
PxlLine floor(a[1,1]), floor(a[2,1]), floor(b[1,1]), floor(b[2,1])
EndIf
EndPrgm
 
FnOff
PlotsOff
ClrDraw
dragon(7, [[75,0,26] [0,75,47] [0,0,1]])</lang>
 
Valid coordinates on the TI-89's graph screen are x 0..76 and y 0..158. This and [[wp:File:Dimensions_fractale_dragon.gif|the outer size of the dragon curve]] were used to choose the position and scale determined by the [[wp:Transformation_matrix#Affine_transformations|transformation matrix]] initially passed to <code>dragon</code> such that the curve will fit onscreen no matter the number of recursions chosen. The height of the curve is 1 unit, so the vertical (and horizontal, to preserve proportions) scale is the height of the screen (rather, one less, to avoid rounding/FP error overrunning), or 75. The curve extends 1/3 unit above its origin, so the vertical translation is (one more than) 1/3 of the scale, or 26. The curve extends 1/3 to the left of its origin, or 25 pixels; the width of the curve is 1.5 units, or 1.5·76 = 114 pixels, and the screen is 159 pixels, so to center it we place the origin at 25 + (159-114)/2 = 47 pixels.
 
=={{header|Vedit macro language}}==
Line 5,177 ⟶ 7,337:
This way we can avoid using any floating point calculations, trigonometric functions etc.
 
<langsyntaxhighlight lang="vedit">File_Open("|(USER_MACRO)\dragon.bmp", OVERWRITE+NOEVENT)
BOF Del_Char(ALL)
 
Line 5,276 ⟶ 7,436:
#10 = #10 >> 8
}
return</langsyntaxhighlight>
 
=={{header|Visual BasicWren}}==
{{trans|Kotlin}}
{{works with|Visual Basic|VB6 Standard}}
{{libheader|DOME}}
<lang vb>Option Explicit
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color
Const Pi As Double = 3.14159265358979
import "dome" for Window
Dim angle As Double
Dim nDepth As Integer
Dim nColor As Long
 
class Game {
Private Sub Form_Load()
static init() {
nColor = vbBlack
Window.title = "Dragon curve"
nDepth = 12
Window.resize(800, 600)
DragonCurve
Canvas.resize(800, 600)
End Sub
var iter = 14
var turns = getSequence(iter)
var startingAngle = -iter * Num.pi / 4
var side = 400 / 2.pow(iter/2)
dragon(turns, startingAngle, side)
}
 
static getSequence(iterations) {
Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
If split = 0 Thenvar turnSequence = []
for (i in 0...iterations) {
xForm.Line -Step(-Cos(angle) * size, Sin(angle) * size), nColor
var copy = []
Else
angle = angle + d * Pi / 4copy.addAll(turnSequence)
Call DragonProc(size / Sqr(2), splitif -(copy.count 1,> 1) copy = copy[-1..0]
angle = angle - d * Pi / 2turnSequence.add(1)
Call DragonProc(size / Sqr(2), splitcopy.each -{ 1,|i| turnSequence.add(-1i) }
angle = angle + d * Pi / 4}
return turnSequence
End If
}
End Sub
Sub DragonCurve()
Const xcoefi = 0.74
Const xcoefl = 0.59
xForm.PSet (xForm.Width * xcoefi, xForm.Height / 3), nColor
Call DragonProc(xForm.Width * xcoefl, nDepth, 1)
End Sub</lang>
 
static dragon(turns, startingAngle, side) {
=={{header|Visual Basic .NET}}==
var col = Color.blue
{{works with|Visual Basic .NET|2013}}
var angle = startingAngle
<lang vbnet>Option Explicit On
var x1 = 230
Imports System.Math
var y1 = 350
var x2 = x1 + (angle.cos * side).truncate
var y2 = y1 + (angle.sin * side).truncate
Canvas.line(x1, y1, x2, y2, col)
x1 = x2
y1 = y2
for (turn in turns) {
angle = angle + turn*Num.pi/2
x2 = x1 + (angle.cos * side).truncate
y2 = y1 + (angle.sin * side).truncate
Canvas.line(x1, y1, x2, y2, col)
x1 = x2
y1 = y2
}
}
 
static update() {}
Public Class DragonCurve
Dim nDepth As Integer = 12
Dim angle As Double
Dim MouseX, MouseY As Integer
Dim CurrentX, CurrentY As Integer
Dim nColor As Color = Color.Black
 
Private Sub DragonCurve_Click(sender As Object, e As EventArgs) Handles Me.Click
SubDragonCurve()
End Sub
 
Sub DrawClear()
Me.CreateGraphics.Clear(Color.White)
End Sub
 
Sub DrawMove(ByVal X As Double, ByVal Y As Double)
CurrentX = X
CurrentY = Y
End Sub
 
Sub DrawLine(ByVal X As Double, ByVal Y As Double)
Dim MyGraph As Graphics = Me.CreateGraphics
Dim PenColor As Pen = New Pen(nColor)
Dim NextX, NextY As Long
NextX = CurrentX + X
NextY = CurrentY + Y
MyGraph.DrawLine(PenColor, CurrentX, CurrentY, NextX, NextY)
CurrentX = NextX
CurrentY = NextY
End Sub
 
Sub DragonProc(size As Double, ByVal split As Integer, d As Integer)
If split = 0 Then
DrawLine(-Cos(angle) * size, Sin(angle) * size)
Else
angle = angle + d * PI / 4
DragonProc(size / Sqrt(2), split - 1, 1)
angle = angle - d * PI / 2
DragonProc(size / Sqrt(2), split - 1, -1)
angle = angle + d * PI / 4
End If
End Sub
 
Sub SubDragonCurve()
Const xcoefi = 0.74, xcoefl = 0.59
DrawClear()
DrawMove(Me.Width * xcoefi, Me.Height / 3)
DragonProc(Me.Width * xcoefl, nDepth, 1)
End Sub
 
static draw(alpha) {}
End Class</lang>
}</syntaxhighlight>
 
=={{header|X86 Assembly}}==
[[File:DragX86.gif|right]]
Translation of XPL0. Assemble with tasm, tlink /t
<langsyntaxhighlight lang="asm"> .model tiny
.code
.486
Line 5,432 ⟶ 7,557:
pop cx
ret
end start</langsyntaxhighlight>
 
=={{header|Xfractint}}==
Line 5,438 ⟶ 7,563:
The <code>xfractint</code> program includes two dragon curves in its lsystem/fractint.l. Here is another version. Xfractint has only a single "F" drawing symbol, so empty symbols X and Y are used for even and odd positions to control the expansion. Each X and each Y is always followed by a single F each.
 
<langsyntaxhighlight Xfractintlang="xfractint">Dragon3 {
Angle 4
Axiom XF
X=XF+Y
Y=XF-Y
}</langsyntaxhighlight>
 
Put this in a file <code>dragon3.l</code> and run as follows. <code>params=8</code> means an 8-order curve.
 
<langsyntaxhighlight lang="sh">xfractint type=lsystem lfile=dragon3.l lname=Dragon3 params=8</langsyntaxhighlight>
 
=={{header|XPL0}}==
[[File:DragonXPL0.gif|right]]
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
proc Dragon(D, P, Q); \Draw a colorful dragon curve
Line 5,476 ⟶ 7,601:
X:= ChIn(1); \wait for keystroke
SetVid(3); \restore normal text mode
]</langsyntaxhighlight>
 
=={{header|zkl}}==
Draw the curve in SVG to stdout.
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="zkl">println(0'|<?xml version='1.0' encoding='utf-8' standalone='no'?>|"\n"
0'|<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'|"\n"
0'|'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>|"\n"
Line 5,505 ⟶ 7,630:
x=dx; y=dy;
}
println("</svg>");</langsyntaxhighlight>
{{out}}
<pre>
Line 5,522 ⟶ 7,647:
</pre>
http://home.comcast.net/~zenkinetic/Images/dragon.svg
 
=={{header|ZX Spectrum Basic}}==
{{trans|BASIC256}}
<lang zxbasic>10 LET level=15: LET insize=120
20 LET x=80: LET y=70
30 LET iters=2^level
40 LET qiter=256/iters
50 LET sq=SQR (2): LET qpi=PI/4
60 LET rotation=0: LET iter=0: LET rq=1
70 DIM r(level)
75 GO SUB 80: STOP
80 REM Dragon
90 IF level>1 THEN GO TO 200
100 LET yn=SIN (rotation)*insize+y
110 LET xn=COS (rotation)*insize+x
120 PLOT x,y: DRAW xn-x,yn-y
130 LET iter=iter+1
140 LET x=xn: LET y=yn
150 RETURN
200 LET insize=insize/sq
210 LET rotation=rotation+rq*qpi
220 LET level=level-1
230 LET r(level)=rq: LET rq=1
240 GO SUB 80
250 LET rotation=rotation-r(level)*qpi*2
260 LET rq=-1
270 GO SUB 80
280 LET rq=r(level)
290 LET rotation=rotation+rq*qpi
300 LET level=level+1
310 LET insize=insize*sq
320 RETURN </lang>
 
{{omit from|AWK}}
{{omit from|Minimal BASIC}}
 
[[Category:Geometry]]
3,048

edits