Dragon Curve Sound

Max Kleiner
6 min readAug 8, 2024

--

I want to show the dragon curve in five language soluitons:

  1. Pascal
  2. Python
  3. Turtle
  4. Delphi
  5. Java Script

A dragon curve is any member of a family of self-similar fractal curves, which can be approximated by recursive methods such as Lindenmayer systems as a procedure in Pascal shows:

procedure Dragon(n,a,t: Integer; d,x,y: Double; var b: TBitmap);
var a1, a2: integer;
begin
if n <= 1 then begin
with b.Canvas do begin
Pen.Color:= random(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;
a1:= (a - t) and 7;
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;

procedure Dragon(n,a,t: Integer; d,x,y: Double; var b: TBitmap);

var a1, a2: integer;

begin

if n <= 1 then begin

with b.Canvas do begin

Pen.Color:= random(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;

a1:= (a - t) and 7;

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;

Recursively a right curling dragon is a right dragon followed by a left dragon, at 90-degree angle. And a left dragon is a left followed by a right. The same you get also with Python and Turtle in maXbox:

Const DRAGFUNC =
'def dragon(level=4, size=200, direction=45): '+LF+
' if level: '+LF+
' right(direction) '+LF+
' dragon(level-1, size/1.41421356237, 45) '+LF+
' left(direction * 2) '+LF+
' dragon(level-1, size/1.41421356237, -45) '+LF+
' right(direction) '+LF+
' else: '+LF+
' forward(size) ';

function PyCodeDragonTurtle(imgpath, aAPIKey: string): string;
begin
with TPythonEngine.Create(Nil) do begin
//pythonhome:= 'C:\Users\User\AppData\Local\Programs\Python\Python312\';
try
loadDLL;
autofinalize:= false;
ExecString('from turtle import right,left,forward,speed, exitonclick,hideturtle');
ExecStr(DRAGFUNC);
ExecStr('speed(0)');
//ExecStr('hideturtle()');
ExecStr('dragon(6)');
ExecStr('exitonclick()');
//result:= (EvalStr('r.json()')); *)
except
raiseError;
finally
Free;
end;
end;
end;

Const DRAGFUNC =

'def dragon(level=4, size=200, direction=45): '+LF+

' if level: '+LF+

' right(direction) '+LF+

' dragon(level-1, size/1.41421356237, 45) '+LF+

' left(direction * 2) '+LF+

' dragon(level-1, size/1.41421356237, -45) '+LF+

' right(direction) '+LF+

' else: '+LF+

' forward(size) ';

function PyCodeDragonTurtle(imgpath, aAPIKey: string): string;

begin

with TPythonEngine.Create(Nil) do begin

//pythonhome:= 'C:\Users\User\AppData\Local\Programs\Python\Python312\';

try

loadDLL;

autofinalize:= false;

ExecString('from turtle import right,left,forward,speed, exitonclick,hideturtle');

ExecStr(DRAGFUNC);

ExecStr('speed(0)');

//ExecStr('hideturtle()');

ExecStr('dragon(6)');

ExecStr('exitonclick()');

//result:= (EvalStr('r.json()')); *)

except

raiseError;

finally

Free;

end;

end;

end;

The dragon curve is probably most commonly thought of as the shape that is generated from repeatedly folding a strip of paper in half.

The script you get at:
Multilanguage Script

https://sourceforge.net/projects/maxbox/files/Examples/13_General/1320_dragon_curve_51_py.txt/download

Turtle Sound

procedure DrawDragon2Sound(step, adir: integer; len:real);
begin
//myturtle:= TJvTurtle.create(self);
with myturtle do begin
if (step >-1) and (len >1) then begin
len:= len /sqrt(2);
Turn(45*adir);
//beep2(440+45, 150)
DrawDragon2(step-1, +1, len);
Turn(-90*adir);
beep2(440-90, 150)
DrawDragon2(step-1, -1, len);
Turn(45*adir);
beep2(440+45, 150)
end else begin //*)
moveforward(len )
//beep2(440, 100)
end;
end;
end;

procedure DrawDragon(step, adir: integer; leng:real);

begin

//myturtle:= TJvTurtle.create(self);

with myturtle do begin

if (step > -1) and (leng > 1) then begin

leng:= leng/sqrt(2);

Turn(45*adir);

DrawDragon(step-1, +1, leng);

Turn(-90*adir);

DrawDragon(step-1, -1, leng);

Turn(45*adir);

end else //*)

//Turtle.Draw(length);

moveforward(leng)

end;

end;

procedure DrawDragon2(step, adir: integer; len:real);

begin

//myturtle:= TJvTurtle.create(self);

with myturtle do begin

if (step >-1) and (len >1) then begin

len:= len /sqrt(2);

Turn(45*adir);

DrawDragon2(step-1, +1, len);

Turn(-90*adir);

DrawDragon2(step-1, -1, len);

Turn(45*adir);

end else //*)

moveforward(len )

end;

end;

procedure DrawDragon2Sound(step, adir: integer; len:real);

begin

//myturtle:= TJvTurtle.create(self);

with myturtle do begin

if (step >-1) and (len >1) then begin

len:= len /sqrt(2);

Turn(45*adir);

//beep2(440+45, 150)

DrawDragon2(step-1, +1, len);

Turn(-90*adir);

beep2(440-90, 150)

DrawDragon2(step-1, -1, len);

Turn(45*adir);

beep2(440+45, 150)

end else begin //*)

moveforward(len )

//beep2(440, 100)

end;

end;

end;

JavaScript Embedded

The Microsoft Edge WebView2 control allows you to embed web technologies (HTML, CSS, and JavaScript) in your native apps. The WebView2 control uses Microsoft Edge as the rendering engine to display the web content in native apps.

<!-- DragonCurve.html -->
<html>
<head>
<script type='text/javascript'>
function pDragon(cId) {
// Plotting Dragon curves. 2/25/17 aev
var n=document.getElementById('ord').value;
var sc=document.getElementById('sci').value;
var hsh=document.getElementById('hshi').value;
var vsh=document.getElementById('vshi').value;
var clr=document.getElementById('cli').value;
var c=c1=c2=c2x=c2y=x=y=0, d=1, n=1<<n;
var cvs=document.getElementById(cId);
var ctx=cvs.getContext("2d");
hsh=Number(hsh); vsh=Number(vsh);
x=y=cvs.width/2;
// Cleaning canvas, init plotting
ctx.fillStyle="white"; ctx.fillRect(0,0,cvs.width,cvs.height);
ctx.beginPath();
for(i=0; i<=n;) {
ctx.lineTo((x+hsh)*sc,(y+vsh)*sc);
c1=c&1; c2=c&2;
c2x=1*d; if(c2>0) {c2x=(-1)*d}; c2y=(-1)*c2x;
if(c1>0) {y+=c2y} else {x+=c2x}
i++; c+=i/(i&-i);
}
ctx.strokeStyle = clr; ctx.stroke();
}
</script>
</head>
<body>
<p><b>Please input order, scale, x-shift, y-shift, color:</></p>
<input id=ord value=11 type="number" min="7" max="25" size="2">
<input id=sci value=7.0 type="number" min="0.001" max="10" size="5">
<input id=hshi value=-265 type="number" min="-50000" max="50000" size="6">
<input id=vshi value=-260 type="number" min="-50000" max="50000" size="6">
<input id=cli value="red" type="text" size="14">
<button onclick="pDragon('canvId')">Plot it!</button>
<h3>Dragon curve</h3>
<canvas id="canvId" width=640 height=640 style="border: 2px inset;"></canvas>
</body>
</html>

<!-- DragonCurve.html -->

<html>

<head>

<script type='text/javascript'>

function pDragon(cId) {

// Plotting Dragon curves. 2/25/17 aev

var n=document.getElementById('ord').value;

var sc=document.getElementById('sci').value;

var hsh=document.getElementById('hshi').value;

var vsh=document.getElementById('vshi').value;

var clr=document.getElementById('cli').value;

var c=c1=c2=c2x=c2y=x=y=0, d=1, n=1<<n;

var cvs=document.getElementById(cId);

var ctx=cvs.getContext("2d");

hsh=Number(hsh); vsh=Number(vsh);

x=y=cvs.width/2;

// Cleaning canvas, init plotting

ctx.fillStyle="white"; ctx.fillRect(0,0,cvs.width,cvs.height);

ctx.beginPath();

for(i=0; i<=n;) {

ctx.lineTo((x+hsh)*sc,(y+vsh)*sc);

c1=c&1; c2=c&2;

c2x=1*d; if(c2>0) {c2x=(-1)*d}; c2y=(-1)*c2x;

if(c1>0) {y+=c2y} else {x+=c2x}

i++; c+=i/(i&-i);

}

ctx.strokeStyle = clr; ctx.stroke();

}

</script>

</head>

<body>

<p><b>Please input order, scale, x-shift, y-shift, color:</></p>

<input id=ord value=11 type="number" min="7" max="25" size="2">

<input id=sci value=7.0 type="number" min="0.001" max="10" size="5">

<input id=hshi value=-265 type="number" min="-50000" max="50000" size="6">

<input id=vshi value=-260 type="number" min="-50000" max="50000" size="6">

<input id=cli value="red" type="text" size="14">

<button onclick="pDragon('canvId')">Plot it!</button>

<h3>Dragon curve</h3>

<canvas id="canvId" width=640 height=640 style="border: 2px inset;"></canvas>

</body>

</html>

The Script you find at:

Dragon Color Samples

In doing variants of color and density by mod operator and direction in moveforward procedure, you get different images of dragon routine:

end else  begin    //*)
moveforward(len )
//beep2(440, 100)
//beep2(440-90*adir, 450)
if (adir= -1) and (cn mod 210=1) then begin
canvas.Pen.Color:= random(clwhite);
if cn mod 1190=1 then
//beep2(440-random(110), 950) }
//PlaySound('INDIGO_WAV', hInstance, SND_RESOURCE or SND_ASYNC);
playreswav('DRUMLOOP','WAV');
end;
inc(cn)
end;

softwareschule.ch/examples/dragonsound.txt

Dragon Color Variations

--

--

Max Kleiner

Max Kleiner's professional environment is in the areas of OOP, UML and coding - among other things as a trainer, developer and consultant.