Dragon curve: Difference between revisions

m
Algol 68 →‎L-System: comments
m (Algol 68 →‎L-System: comments)
 
(31 intermediate revisions by 11 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!}}==
Line 195 ⟶ 351:
 
=={{header|ALGOL 68}}==
 
===Animated===
 
{{trans|python}}
<!-- {{works with|ALGOL 68|Standard - but ''draw'' is not part of the standard prelude}} -->
Line 367 ⟶ 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}}==
Line 422 ⟶ 650:
And TRS-80 BASIC code in Dan Rollins, "A Tiger Meets a Dragon: An examination of the mathematical properties of dragon curves and a program to print them on an IDS Paper Tiger", Byte Magazine, December 1983. (Based on generating a string of turns by appending middle turn and reversed copy. Options for the middle turn give the alternate paper folding curve and more too. The turns are then followed for the plot.)
* https://archive.org/details/byte-magazine-1983-12
 
==={{header|ANSI BASIC}}===
{{trans|QuickBASIC|Internal subprogram is used, so it has access to program (global) variables.}}
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">
100 PROGRAM DragonCurve
110 DECLARE SUB Dragon
120 SET WINDOW 0, 639, 0, 399
130 SET AREA COLOR 1
140 SET COLOR MIX(1) 0, 0, 0
150 REM SIN, COS in arrays for PI/4 multipl.
160 DIM S(0 TO 7), C(0 TO 7)
170 LET QPI = PI / 4
180 FOR I = 0 TO 7
190 LET S(I) = SIN(I * QPI)
200 LET C(I) = COS(I * QPI)
210 NEXT I
220 REM ** Initialize variables non-local for SUB Dragon.
230 LET SQ = SQR(2)
240 LET X = 224
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}}===
Line 513 ⟶ 782:
90 x = 224 : y = 140
100 sq = sqr(2)
110 rotqpi = 0 : iter = 0 : rq = 1
120 dim r(level)
130 graphics 0 : graphics cls
Line 519 ⟶ 788:
150 end
160 rem Dragon
170 if rotqpi <= 0rotqpi thenand 7
180 if level rotqpi <= rotqpi+81 then
190 yn = s(rotqpi)*insize+y
190 else
200 if rotqpi > 7 then rotqpixn = c(rotqpi-8)*insize+x
210 graphics moveto x,y : graphics lineto xn,yn
210 endif
220 if level >x 1= thenxn goto: 290y = yn
230 else
230 yn = s(rotqpi)*insize+y
240 xn insize = c(rotqpi)*insize+x*sq/2
250 rotqpi = (rotqpi+rq) and 7
250 graphics moveto x,y : graphics lineto xn,yn
260 iter level = iter+level-1
270 x r(level) = xnrq : yrq = yn1
280 return gosub 160
290 insize rotqpi = insize(rotqpi-r(level)*sq/2) and 7
300 rotqpi = rotqpi+rq = -1
310 if rotqpi < 0 thengosub 160
320 rotqpirq = rotqpi+8r(level)
330 rotqpi = (rotqpi+rq) and 7
330 else
340 if rotqpi > 7 then rotqpilevel = rotqpi-8level+1
350 insize = insize*sq
350 endif
360 level = level-1endif
370 return
370 r(level) = rq : rq = 1
380 gosub 160
390 rotqpi = rotqpi-r(level)*2
400 if rotqpi < 0 then
410 rotqpi = rotqpi+8
420 else
430 if rotqpi > 7 then rotqpi = rotqpi-8
440 endif
450 rq = -1
460 gosub 160
470 rq = r(level)
480 rotqpi = rotqpi+rq
490 if rotqpi < 0 then
500 rotqpi = rotqpi+8
510 else
520 if rotqpi > 7 then rotqpi = rotqpi-8
530 endif
540 level = level+1
550 insize = insize*sq
560 return
</syntaxhighlight>
 
Line 569 ⟶ 819:
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
70 C(I)=COS(I*QPI)
80 NEXT ILEVEL=15
90 INSIZE=128:REM 2^WHOLE_NUM (LOOKS BETTER)
90 LEVEL=15
100 X=112:Y=70
100 INSIZE=128:REM 2^WHOLE_NUM (LOOKS BETTER)
110 XROTQPI=1120:RQ=1
120 Y=70DIM R(LEVEL)
130 SQ=SQR(GRAPHIC 2),1
140 GOSUB 160
140 ROTQPI=0:ITER=0:RQ=1
150 DIM R(LEVEL)END
160 GRAPHICREM 2,1DRAGON
170 GOSUBROTQPI=ROTQPI 190AND 7
180 IF LEVEL>1 THEN GO TO 240
180 END
190 YN=S(ROTQPI)*INSIZE+Y
190 REM DRAGON
200 IF ROTQPI<0 THEN ROTQPIXN=C(ROTQPI)*INSIZE+8:GOTO 220X
210 DRAW ,X,Y TO XN,YN
210 IF ROTQPI>7 THEN ROTQPI=ROTQPI-8
220 X=XN:Y=YN
220 IF LEVEL>1 THEN GO TO 290
230 RETURN
230 YN=S(ROTQPI)*INSIZE+Y
240 XNINSIZE=C(ROTQPI)*INSIZE+X*SQ/2
250 ROTQPI=(ROTQPI+RQ)AND 7
250 DRAW ,X,Y TO XN,YN
260 ITERLEVEL=ITER+LEVEL-1
270 XR(LEVEL)=XNRQ:YRQ=YN1
280 RETURNGOSUB 160
290 ROTQPI=(ROTQPI-R(LEVEL)*2)AND 7
290 INSIZE=INSIZE*SQ/2
300 ROTQPI=ROTQPI+RQ=-1
310 GOSUB 160
310 IF ROTQPI<0 THEN ROTQPI=ROTQPI+8:GOTO 330
320 RQ=R(LEVEL)
320 IF ROTQPI>7 THEN ROTQPI=ROTQPI-8
330 ROTQPI=(ROTQPI+RQ)AND 7
330 LEVEL=LEVEL-1
340 R(LEVEL)=RQ:RQ=LEVEL+1
350 INSIZE=INSIZE*SQ
350 GOSUB 190
360 RETURN
360 ROTQPI=ROTQPI-R(LEVEL)*2
370 IF ROTQPI<0 THEN ROTQPI=ROTQPI+8:GOTO 390
380 IF ROTQPI>7 THEN ROTQPI=ROTQPI-8
390 RQ=-1
400 GOSUB 190
410 RQ=R(LEVEL)
420 ROTQPI=ROTQPI+RQ
430 IF ROTQPI<0 THEN ROTQPI=ROTQPI+8:GOTO 450
440 IF ROTQPI>7 THEN ROTQPI=ROTQPI-8
450 LEVEL=LEVEL+1
460 INSIZE=INSIZE*SQ
470 RETURN
</syntaxhighlight>
 
Line 642 ⟶ 881:
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}}===
Line 664 ⟶ 945:
 
==={{header|Liberty BASIC}}===
{{works with|Just BASIC}}
<syntaxhighlight lang="lb">nomainwin
mainwin 50 20
Line 720 ⟶ 1,002:
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}}===
Line 761 ⟶ 1,088:
 
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}}===
Line 864 ⟶ 1,225:
 
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}}===
Line 1,113 ⟶ 1,608:
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}}===
Line 1,118 ⟶ 1,642:
<syntaxhighlight lang="zxbasic">10 LET level=15: LET insize=120
20 LET x=80: LET y=70
30 LET iterssq=SQR (2^level): LET qpi=PI/4
40 LET qiterrotation=256/iters0: LET rq=1
50 DIM r(level)
50 LET sq=SQR (2): LET qpi=PI/4
60 GO SUB 70: STOP
60 LET rotation=0: LET iter=0: LET rq=1
70 DIMREM r(level)Dragon
80 IF level>1 THEN GO TO 140
75 GO SUB 80: STOP
90 LET yn=SIN (rotation)*insize+y
80 REM Dragon
100 LET xn=COS (rotation)*insize+x
90 IF level>1 THEN GO TO 200
110 PLOT x,y: DRAW xn-x,yn-y
100 LET yn=SIN (rotation)*insize+y
110120 LET xnx=COSxn: (rotation)*insize+xLET y=yn
130 RETURN
120 PLOT x,y: DRAW xn-x,yn-y
130140 LET iterinsize=iter+1insize/sq
150 LET rotation=rotation+rq*qpi
140 LET x=xn: LET y=yn
160 LET level=level-1
150 RETURN
200170 LET insizer(level)=insize/sqrq: LET rq=1
180 GO SUB 70
210 LET rotation=rotation+rq*qpi
220190 LET levelrotation=rotation-r(level-1)*qpi*2
230 LET r(level)=rq:200 LET rq=-1
240210 GO SUB 8070
250220 LET rotationrq=rotation-r(level)*qpi*2
230 LET rotation=rotation+rq*qpi
260 LET rq=-1
240 LET level=level+1
270 GO SUB 80
280250 LET rqinsize=r(level)insize*sq
260 RETURN </syntaxhighlight>
290 LET rotation=rotation+rq*qpi
300 LET level=level+1
310 LET insize=insize*sq
320 RETURN </syntaxhighlight>
 
=={{header|Befunge}}==
Line 1,605 ⟶ 2,126:
//-----------------------------------------------------------------------------------------
</syntaxhighlight>
 
=={{header|Clojure}}==
Calculates the absolute location of each step iteratively by bit-twiddling and then prints terminal output with unicode box-drawing characters:
<syntaxhighlight lang="clojure">(defn i->dir
[n]
(mod (Long/bitCount (bit-xor n (bit-shift-right n 1))) 4))
 
(defn safe-bit-or [v bit] (bit-or (or v 0) bit))
 
(let [steps 511
{[minx maxx miny maxy] :bbox data :data}
(loop [i 0
[x y] [0 0]
out {}
[minx maxx miny maxy] [0 0 0 0]]
(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:
 
[[File:Clj-dragon-terminal-screenshot.png|alt=terminal output of Clojure dragon curve program]]
 
=={{header|COBOL}}==
Line 2,153 ⟶ 2,710:
=={{header|EasyLang}}==
 
[https://easylang.dev/show/#cod=jU7NDoIwDL73Kb7Em4ZZSDDxwMMQNnHJ3HQjCD69ZWDiwYO9tF/7/bQLLkRwzeSsN0+rhytY1TShQVXTLO3EdAujwYSZWt87IzumHegeQwcd2z54JPsycGaEhoIiAPaS8cJFrglFgy4krCb7rNluMw6NYP/rtjyWw2U2Ln3W38FHpEccUOXEAiXKjbTaSa4WzzP/Iy2yVpGijXZilJU4vgE= Run it]
[https://easylang.online/apps/_dragon-curve.html Run it]
 
<syntaxhighlight lang="text">color 050
color 050
linewidth 0.5
x = 25
Line 2,162 ⟶ 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</syntaxhighlight>
</syntaxhighlight>
 
=={{header|Elm}}==
Line 2,573 ⟶ 3,132:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Dragon_curve}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''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]]
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - L-system - Dragon curve (rounded) 02.png]]
In '''[https://formulae.org/?example=Dragon_curve this]''' page you can see the program(s) related to this task and their results.
 
=={{header|Gnuplot}}==
Line 5,597 ⟶ 6,180:
right ] resolves left ( n --> )
turtle
20 frames
-260 1 fly
3 4 turn
100 1 fly
5 8 turn
11 left</syntaxhighlight>
1 frames</syntaxhighlight>
 
{{output}}
Line 6,856 ⟶ 7,441:
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="ecmascriptwren">import "graphics" for Canvas, Color
import "dome" for Window
 
3,026

edits