Hilbert curve: Difference between revisions

105,627 bytes added ,  1 month ago
m
→‎{{header|Quackery}}: added link to description of method
(→‎{{header|JavaScript}}: Added a functional variant (serializing a tree generated by a production rule), applied JSBeautify to both.)
m (→‎{{header|Quackery}}: added link to description of method)
 
(114 intermediate revisions by 43 users not shown)
Line 3:
;Task
 
Produce a graphical or ASCII-art representation of a [[wp:Hilbert curve|Hilbert curve]] of at least order 3.
 
=={{header|11l}}==
{{trans|D}}
 
<syntaxhighlight lang="11l">T Point
x = 0
y = 0
 
F rot(n, rx, ry)
I !ry
I rx
.x = (n - 1) - .x
.y = (n - 1) - .y
 
swap(&.x, &.y)
 
F calcD(n)
V d = 0
V s = n >> 1
L s > 0
V rx = ((.x [&] s) != 0)
V ry = ((.y [&] s) != 0)
d += s * s * ((I rx {3} E 0) (+) (I ry {1} E 0))
.rot(s, rx, ry)
s >>= 1
R d
 
F fromD(n, d)
V p = Point()
V t = d
V s = 1
L s < n
V rx = ((t [&] 2) != 0)
V ry = (((t (+) (I rx {1} E 0)) [&] 1) != 0)
p.rot(s, rx, ry)
p.x += (I rx {s} E 0)
p.y += (I ry {s} E 0)
t >>= 2
s <<= 1
R p
 
F getPointsForCurve(n)
[Point] points
L(d) 0 .< n * n
points [+]= fromD(n, d)
R points
 
F drawCurve(points, n)
V canvas = [[‘ ’] * (n * 3 - 2)] * n
 
L(i) 1 .< points.len
V lastPoint = points[i - 1]
V curPoint = points[i]
V deltaX = curPoint.x - lastPoint.x
V deltaY = curPoint.y - lastPoint.y
I deltaX == 0
assert(deltaY != 0, ‘Duplicate point’)
V row = max(curPoint.y, lastPoint.y)
V col = curPoint.x * 3
canvas[row][col] = ‘|’
E
assert(deltaY == 0, ‘Diagonal line’)
V row = curPoint.y
V col = min(curPoint.x, lastPoint.x) * 3 + 1
canvas[row][col] = ‘_’
canvas[row][col + 1] = ‘_’
 
[String] lines
L(row) canvas
lines [+]= row.join(‘’)
R lines
 
L(order) 1..5
V n = 1 << order
V points = getPointsForCurve(n)
print(‘Hilbert curve, order=’order)
V lines = drawCurve(points, n)
L(line) lines
print(line)
print()</syntaxhighlight>
 
{{out}}
<pre>
Hilbert curve, order=1
|__|
 
Hilbert curve, order=2
__ __
__| |__
| __ |
|__| |__|
 
Hilbert curve, order=3
__ __ __ __
|__| __| |__ |__|
__ |__ __| __
| |__ __| |__ __| |
|__ __ __ __ __|
__| |__ __| |__
| __ | | __ |
|__| |__| |__| |__|
 
Hilbert curve, order=4
__ __ __ __ __ __ __ __ __ __
__| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__|
 
Hilbert curve, order=5
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
|__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__|
__ |__ __| __ | __ | __ |__ __| __ | __ | __ |__ __| __
| |__ __| |__ __| | |__| |__| | |__ __| |__ __| | |__| |__| | |__ __| |__ __| |
...
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|
 
</pre>
 
=={{header|Action!}}==
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed.
<syntaxhighlight lang="action!">DEFINE MAXSIZE="12"
 
INT ARRAY
dxStack(MAXSIZE),dyStack(MAXSIZE)
BYTE ARRAY
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 dx,dy BYTE depth,stage)
IF IsFull() THEN Break() FI
dxStack(stacksize)=dx dyStack(stacksize)=dy
depthStack(stacksize)=depth
stageStack(stackSize)=stage
stacksize==+1
RETURN
 
PROC Pop(INT POINTER dx,dy BYTE POINTER depth,stage)
IF IsEmpty() THEN Break() FI
stacksize==-1
dx^=dxStack(stacksize) dy^=dyStack(stacksize)
depth^=depthStack(stacksize)
stage^=stageStack(stacksize)
RETURN
 
PROC DrawHilbert(INT x BYTE y INT dx,dy BYTE depth)
BYTE stage
Plot(x,y)
Push(dx,dy,depth,0)
 
WHILE IsEmpty()=0
DO
Pop(@dx,@dy,@depth,@stage)
IF stage<3 THEN
Push(dx,dy,depth,stage+1)
FI
IF stage=0 THEN
IF depth>1 THEN
Push(dy,dx,depth-1,0)
FI
ELSEIF stage=1 THEN
x==+dx y==+dy
DrawTo(x,y)
IF depth>1 THEN
Push(dx,dy,depth-1,0)
FI
ELSEIF stage=2 THEN
x==+dy y==+dx
DrawTo(x,y)
IF depth>1 THEN
Push(dx,dy,depth-1,0)
FI
ELSEIF stage=3 THEN
x==-dx y==-dy
DrawTo(x,y)
IF depth>1 THEN
Push(-dy,-dx,depth-1,0)
FI
FI
OD
RETURN
 
PROC Main()
BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
 
Graphics(8+16)
Color=1
COLOR1=$0C
COLOR2=$02
 
DrawHilbert(64,1,0,3,6)
 
DO UNTIL CH#$FF OD
CH=$FF
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Hilbert_curve.png Screenshot from Atari 8-bit computer]
 
=={{header|Ada}}==
{{libheader|APDF}}
<syntaxhighlight lang="ada">with PDF_Out; use PDF_Out;
 
procedure Hilbert_Curve_PDF is
 
Length : constant := 500.0;
Corner : constant Point := (50.0, 300.0);
 
type Rule_Type is (A, B, C, D);
 
PDF : PDF_Out.Pdf_Out_File;
First : Boolean;
 
procedure Hilbert (Order : in Natural;
Rule : in Rule_Type;
Length : in Real;
X, Y : in Real)
is
L : constant Real := Length / 4.0;
begin
if Order = 0 then
if First then
First := False;
PDF.Move (Corner + (X, Y));
else
PDF.Line (Corner + (X, Y));
end if;
else
case Rule is
when A =>
Hilbert (Order - 1, D, 2.0 * L, X - L, Y + L);
Hilbert (Order - 1, A, 2.0 * L, X - L, Y - L);
Hilbert (Order - 1, A, 2.0 * L, X + L, Y - L);
Hilbert (Order - 1, B, 2.0 * L, X + L, Y + L);
when B =>
Hilbert (Order - 1, C, 2.0 * L, X + L, Y - L);
Hilbert (Order - 1, B, 2.0 * L, X - L, Y - L);
Hilbert (Order - 1, B, 2.0 * L, X - L, Y + L);
Hilbert (Order - 1, A, 2.0 * L, X + L, Y + L);
when C =>
Hilbert (Order - 1, B, 2.0 * L, X + L, Y - L);
Hilbert (Order - 1, C, 2.0 * L, X + L, Y + L);
Hilbert (Order - 1, C, 2.0 * L, X - L, Y + L);
Hilbert (Order - 1, D, 2.0 * L, X - L, Y - L);
when D =>
Hilbert (Order - 1, A, 2.0 * L, X - L, Y + L);
Hilbert (Order - 1, D, 2.0 * L, X + L, Y + L);
Hilbert (Order - 1, D, 2.0 * L, X + L, Y - L);
Hilbert (Order - 1, C, 2.0 * L, X - L, Y - L);
end case;
end if;
end Hilbert;
 
procedure Hilbert (Order : Natural; Color : Color_Type) is
begin
First := True;
PDF.Stroking_Color (Color);
Hilbert (Order, A, Length, Length / 2.0, Length / 2.0);
PDF.Finish_Path (Close_Path => False,
Rendering => Stroke,
Rule => Nonzero_Winding_Number);
end Hilbert;
 
begin
PDF.Create ("hilbert.pdf");
PDF.Page_Setup (A4_Portrait);
PDF.Line_Width (2.0);
 
PDF.Color (Black);
PDF.Draw (Corner + (0.0, 0.0, Length, Length), Fill);
 
Hilbert (6, Color => (0.9, 0.1, 0.8));
Hilbert (5, Color => (0.0, 0.9, 0.0));
 
PDF.Close;
end Hilbert_Curve_PDF;</syntaxhighlight>
 
=={{header|ALGOL 68}}==
This generates the curve following the L-System rules described in the Wikipedia article.
 
{| class="wikitable"
| '''L-System rule''' || ''A'' || ''B'' || ''F'' || '''+''' || '''-'''
|-
| '''Procedure''' || a || b || forward || right || left
|}
 
<syntaxhighlight lang="algol68">BEGIN
INT level = 4; # <-- change this #
 
INT side = 2**level * 2 - 2;
[-side:1, 0:side]STRING grid;
INT x := 0, y := 0, dir := 0;
INT old dir := -1;
INT e=0, n=1, w=2, s=3;
 
FOR i FROM 1 LWB grid TO 1 UPB grid DO
FOR j FROM 2 LWB grid TO 2 UPB grid DO grid[i,j] := " "
OD OD;
 
PROC left = VOID: dir := (dir + 1) MOD 4;
PROC right = VOID: dir := (dir - 1) MOD 4;
PROC move = VOID: (
CASE dir + 1 IN
# e: # x +:= 1, # n: # y -:= 1, # w: # x -:= 1, # s: # y +:= 1
ESAC
);
PROC forward = VOID: (
# draw corner #
grid[y, x] := CASE old dir + 1 IN
# e # CASE dir + 1 IN "──", "─╯", " ?", "─╮" ESAC,
# n # CASE dir + 1 IN " ╭", " │", "─╮", " ?" ESAC,
# w # CASE dir + 1 IN " ?", " ╰", "──", " ╭" ESAC,
# s # CASE dir + 1 IN " ╰", " ?", "─╯", " │" ESAC
OUT " "
ESAC;
move;
# draw segment #
grid[y, x] := IF dir = n OR dir = s THEN " │" ELSE "──" FI;
# advance to next corner #
move;
old dir := dir
);
 
PROC a = (INT level)VOID:
IF level > 0 THEN
left; b(level-1); forward; right; a(level-1); forward;
a(level-1); right; forward; b(level-1); left
FI,
b = (INT level)VOID:
IF level > 0 THEN
right; a(level-1); forward; left; b(level-1); forward;
b(level-1); left; forward; a(level-1); right
FI;
 
# draw #
a(level);
 
# print #
FOR row FROM 1 LWB grid TO 1 UPB grid DO
print((grid[row,], new line))
OD
END
</syntaxhighlight>
{{out}}
<pre> ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
│ ╰───╯ │ │ ╰───╯ │ │ ╰───╯ │ │ ╰───╯ │
│ │ │ │ │ │ │ │
╰───╮ ╭───╯ ╰───╮ ╭───╯ ╰───╮ ╭───╯ ╰───╮ ╭───╯
│ │ │ │ │ │ │ │
╭───╯ ╰───────────╯ ╰───╮ ╭───╯ ╰───────────╯ ╰───╮
│ │ │ │
│ ╭───────╮ ╭───────╮ │ │ ╭───────╮ ╭───────╮ │
│ │ │ │ │ │ │ │ │ │ │ │
╰───╯ ╭───╯ ╰───╮ ╰───╯ ╰───╯ ╭───╯ ╰───╮ ╰───╯
│ │ │ │
╭───╮ ╰───╮ ╭───╯ ╭───╮ ╭───╮ ╰───╮ ╭───╯ ╭───╮
│ │ │ │ │ │ │ │ │ │ │ │
│ ╰───────╯ ╰───────╯ ╰───╯ ╰───────╯ ╰───────╯ │
│ │
╰───╮ ╭───────╮ ╭───────╮ ╭───────╮ ╭───────╮ ╭───╯
│ │ │ │ │ │ │ │ │ │
╭───╯ ╰───╮ ╰───╯ ╭───╯ ╰───╮ ╰───╯ ╭───╯ ╰───╮
│ │ │ │ │ │
│ ╭───╮ │ ╭───╮ ╰───╮ ╭───╯ ╭───╮ │ ╭───╮ │
│ │ │ │ │ │ │ │ │ │ │ │ │ │
╰───╯ ╰───╯ │ ╰───────╯ ╰───────╯ │ ╰───╯ ╰───╯
│ │
╭───╮ ╭───╮ │ ╭───────╮ ╭───────╮ │ ╭───╮ ╭───╮
│ │ │ │ │ │ │ │ │ │ │ │ │ │
│ ╰───╯ │ ╰───╯ ╭───╯ ╰───╮ ╰───╯ │ ╰───╯ │
│ │ │ │ │ │
╰───╮ ╭───╯ ╭───╮ ╰───╮ ╭───╯ ╭───╮ ╰───╮ ╭───╯
│ │ │ │ │ │ │ │ │ │
───╯ ╰───────╯ ╰───────╯ ╰───────╯ ╰───────╯ ╰──
</pre>
 
=={{header|AutoHotkey}}==
{{trans|Go}}
Requires [https://www.autohotkey.com/boards/viewtopic.php?t=6517 Gdip Library]
<syntaxhighlight lang="autohotkey">gdip1()
HilbertX := A_ScreenWidth/2 - 100, HilbertY := A_ScreenHeight/2 - 100
Hilbert(HilbertX, HilbertY, 2**5, 5, 5, Arr:=[])
xmin := xmax := ymin := ymax := 0
for i, point in Arr
{
xmin := A_Index = 1 ? point.x : xmin < point.x ? xmin : point.x
xmax := point.x > xmax ? point.x : xmax
ymin := A_Index = 1 ? point.y : ymin < point.y ? ymin : point.y
ymax := point.y > ymax ? point.y : ymax
}
for i, point in Arr
points .= point.x - xmin + HilbertX "," point.y - ymin + HilbertY "|"
points := Trim(points, "|")
Gdip_DrawLines(G, pPen, Points)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
return
; ---------------------------------------------------------------
Hilbert(x, y, lg, i1, i2, Arr) {
if (lg = 1) {
Arr[Arr.count()+1, "x"] := x
Arr[Arr.count(), "y"] := y
return
}
lg /= 2
Hilbert(x+i1*lg , y+i1*lg , lg , i1 , 1-i2 , Arr)
Hilbert(x+i2*lg , y+(1-i2)*lg , lg , i1 , i2 , Arr)
Hilbert(x+(1-i1)*lg , y+(1-i1)*lg , lg , i1 , i2 , Arr)
Hilbert(x+(1-i2)*lg , y+i2*lg , lg , 1-i1 , i2 , Arr)
}
; ---------------------------------------------------------------
gdip1(){
global
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
Width := A_ScreenWidth, Height := A_ScreenHeight
Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 1: Show, NA
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pPen := Gdip_CreatePen(0xFFFF0000, 2)
}
; ---------------------------------------------------------------
gdip2(){
global
Gdip_DeleteBrush(pBrush)
Gdip_DeletePen(pPen)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
}
; ---------------------------------------------------------------
Exit:
gdip2()
Gdip_Shutdown(pToken)
ExitApp
Return</syntaxhighlight>
 
=={{header|Binary Lambda Calculus}}==
 
As shown in https://www.ioccc.org/2012/tromp/hint.html, the 142+3 byte BLC program
 
<pre>0000000 18 18 18 18 11 11 54 68 06 04 15 5f f0 41 9d f9
0000020 de 16 ff fe 5f 3f ef f6 15 ff 94 68 40 58 11 7e
0000040 05 cb fe bc bf ee 86 cb 94 68 16 00 5c 0b fa cb
0000060 fb f7 1a 85 e0 5c f4 14 d5 fe 08 18 0b 04 8d 08
0000100 00 e0 78 01 64 45 ff e5 ff 7f ff fe 5f ff 2f c0
0000120 ee d9 7f 5b ff ff fb ff fc aa ff f7 81 7f fa df
0000140 76 69 54 68 06 01 57 f7 e1 60 5c 13 fe 80 b2 2c
0000160 18 58 1b fe 5c 10 42 ff 80 5d ee c0 6c 2c 0c 06
0000200 08 19 1a 00 16 7f bc bc fd f6 5f 7c 0a 20 31 32
0000220 33</pre>
 
(consisting of the 142 byte binary prefix https://github.com/tromp/AIT/blob/master/hilbert followed by "123") outputs the 3rd order Hilbert curve
 
<pre> _ _ _ _
| |_| | | |_| |
|_ _| |_ _|
_| |_____| |_
| ___ ___ |
|_| _| |_ |_|
_ |_ _| _
| |___| |___| |</pre>
 
=={{header|BQN}}==
{{trans|J}}
BQN does not have complex numbers as of the creation of this submission, so <code>Conj</code> and <code>CMul</code> implement complex number operations on two element arrays, for clarity's sake.
 
<syntaxhighlight lang="bqn">Conj←1‿¯1⊸×
Cmul←-´∘×⋈+´∘×⟜⌽
Iter←(⊢∾⟨1‿0⟩∾Conj¨∘⌽)∘(0‿¯1⊸CMul¨∘⌽∾⟨0‿¯1⟩∾⊢)
Plot←{•Plot´<˘⍉>+`⟨0‿0⟩∾Iter⍟𝕩 ⟨⟩}</syntaxhighlight>
 
This program is made for <code>•Plot</code> in the online implementation, and you can view the result in the [https://mlochbaum.github.io/BQN/try.html#code=Q29uauKGkDHigL/CrzHiirjDlwpDbXVs4oaQLcK04oiYw5fii4grwrTiiJjDl+KfnOKMvQpJdGVy4oaQKOKKouKIvuKfqDHigL8w4p+p4oi+Q29uasKo4oiY4oy9KeKImCgw4oC/wq8x4oq4Q011bMKo4oiY4oy94oi+4p+oMOKAv8KvMeKfqeKIvuKKoikKSGlsYmVydOKGkHvigKJQbG90wrQ8y5jijYk+K2Din6gw4oC/MOKfqeKIvkl0ZXLijZ/wnZWpIOKfqOKfqX0KIApIaWxiZXJ0IDU= Online REPL.]
 
=={{header|C}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="c">#include <stdio.h>
 
#define N 32
Line 77 ⟶ 582:
}
return 0;
}</langsyntaxhighlight>
{{output}}
<pre>Same as Kotlin entry.</pre>
 
=={{header|C sharp|C#}}==
{{trans|Visual Basic .NET}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
 
namespace HilbertCurve {
class Program {
static void Swap<T>(ref T a, ref T b) {
var c = a;
a = b;
b = c;
}
 
struct Point {
public int x, y;
 
public Point(int x, int y) {
this.x = x;
this.y = y;
}
 
//rotate/flip a quadrant appropriately
public void Rot(int n, bool rx, bool ry) {
if (!ry) {
if (rx) {
x = (n - 1) - x;
y = (n - 1) - y;
}
Swap(ref x, ref y);
}
}
 
public override string ToString() {
return string.Format("({0}, {1})", x, y);
}
}
 
static Point FromD(int n, int d) {
var p = new Point(0, 0);
int t = d;
 
for (int s = 1; s < n; s <<= 1) {
var rx = (t & 2) != 0;
var ry = ((t ^ (rx ? 1 : 0)) & 1) != 0;
p.Rot(s, rx, ry);
p.x += rx ? s : 0;
p.y += ry ? s : 0;
t >>= 2;
}
 
return p;
}
 
static List<Point> GetPointsForCurve(int n) {
var points = new List<Point>();
int d = 0;
while (d < n * n) {
points.Add(FromD(n, d));
d += 1;
}
return points;
}
 
static List<string> DrawCurve(List<Point> points, int n) {
var canvas = new char[n, n * 3 - 2];
for (int i = 0; i < canvas.GetLength(0); i++) {
for (int j = 0; j < canvas.GetLength(1); j++) {
canvas[i, j] = ' ';
}
}
 
for (int i = 1; i < points.Count; i++) {
var lastPoint = points[i - 1];
var curPoint = points[i];
var deltaX = curPoint.x - lastPoint.x;
var deltaY = curPoint.y - lastPoint.y;
if (deltaX == 0) {
Debug.Assert(deltaY != 0, "Duplicate point");
//vertical line
int row = Math.Max(curPoint.y, lastPoint.y);
int col = curPoint.x * 3;
canvas[row, col] = '|';
} else {
Debug.Assert(deltaY == 0, "Duplicate point");
//horizontal line
var row = curPoint.y;
var col = Math.Min(curPoint.x, lastPoint.x) * 3 + 1;
canvas[row, col] = '_';
canvas[row, col + 1] = '_';
}
}
 
var lines = new List<string>();
for (int i = 0; i < canvas.GetLength(0); i++) {
var sb = new StringBuilder();
for (int j = 0; j < canvas.GetLength(1); j++) {
sb.Append(canvas[i, j]);
}
lines.Add(sb.ToString());
}
return lines;
}
 
static void Main() {
for (int order = 1; order <= 5; order++) {
var n = 1 << order;
var points = GetPointsForCurve(n);
Console.WriteLine("Hilbert curve, order={0}", order);
var lines = DrawCurve(points, n);
foreach (var line in lines) {
Console.WriteLine(line);
}
Console.WriteLine();
}
}
}
}</syntaxhighlight>
{{out}}
<pre>Hilbert curve, order=1
 
|__|
 
Hilbert curve, order=2
__ __
__| |__
| __ |
|__| |__|
 
Hilbert curve, order=3
__ __ __ __
|__| __| |__ |__|
__ |__ __| __
| |__ __| |__ __| |
|__ __ __ __ __|
__| |__ __| |__
| __ | | __ |
|__| |__| |__| |__|
 
Hilbert curve, order=4
__ __ __ __ __ __ __ __ __ __
__| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__|
 
Hilbert curve, order=5
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
|__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__|
__ |__ __| __ | __ | __ |__ __| __ | __ | __ |__ __| __
| |__ __| |__ __| | |__| |__| | |__ __| |__ __| | |__| |__| | |__ __| |__ __| |
|__ __ __ __ __| __ __ | __ __ __ __ | __ __ |__ __ __ __ __|
__| |__ __| |__ | |__| | |__| __| |__ |__| | |__| | __| |__ __| |__
| __ | | __ | |__ __| __ |__ __| __ |__ __| | __ | | __ |
|__| |__| |__| |__| __| |__ __| |__ __| |__ __| |__ __| |__ |__| |__| |__| |__|
__ __ __ __ |__ __ __ __ __ __ __ __ __ __| __ __ __ __
| |__| | | |__| | __| |__ |__| __| |__ |__| __| |__ | |__| | | |__| |
|__ __| |__ __| | __ | __ |__ __| __ | __ | |__ __| |__ __|
__| |__ __ __| |__ |__| |__| | |__ __| |__ __| | |__| |__| __| |__ __ __| |__
| __ __ __ __ | __ __ | __ __ __ __ | __ __ | __ __ __ __ |
|__| __| |__ |__| | |__| | |__| __| |__ |__| | |__| | |__| __| |__ |__|
__ |__ __| __ |__ __| __ |__ __| __ |__ __| __ |__ __| __
| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |
|__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __|
__| |__ |__| __| |__ |__| __| |__ __| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ | | __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__| |__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __ __ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| | | |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __| |__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ | | __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __ __ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</pre>
 
=={{header|C++}}==
{{trans|D}}
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <vector>
 
struct Point {
int x, y;
 
//rotate/flip a quadrant appropriately
void rot(int n, bool rx, bool ry) {
if (!ry) {
if (rx) {
x = (n - 1) - x;
y = (n - 1) - y;
}
std::swap(x, y);
}
}
};
 
Point fromD(int n, int d) {
Point p = { 0, 0 };
bool rx, ry;
int t = d;
for (int s = 1; s < n; s <<= 1) {
rx = ((t & 2) != 0);
ry = (((t ^ (rx ? 1 : 0)) & 1) != 0);
p.rot(s, rx, ry);
p.x += (rx ? s : 0);
p.y += (ry ? s : 0);
t >>= 2;
}
return p;
}
 
std::vector<Point> getPointsForCurve(int n) {
std::vector<Point> points;
for (int d = 0; d < n * n; ++d) {
points.push_back(fromD(n, d));
}
return points;
}
 
std::vector<std::string> drawCurve(const std::vector<Point> &points, int n) {
auto canvas = new char *[n];
for (size_t i = 0; i < n; i++) {
canvas[i] = new char[n * 3 - 2];
std::memset(canvas[i], ' ', n * 3 - 2);
}
 
for (int i = 1; i < points.size(); i++) {
auto lastPoint = points[i - 1];
auto curPoint = points[i];
int deltaX = curPoint.x - lastPoint.x;
int deltaY = curPoint.y - lastPoint.y;
if (deltaX == 0) {
// vertical line
int row = std::max(curPoint.y, lastPoint.y);
int col = curPoint.x * 3;
canvas[row][col] = '|';
} else {
// horizontal line
int row = curPoint.y;
int col = std::min(curPoint.x, lastPoint.x) * 3 + 1;
canvas[row][col] = '_';
canvas[row][col + 1] = '_';
}
}
 
std::vector<std::string> lines;
for (size_t i = 0; i < n; i++) {
std::string temp;
temp.assign(canvas[i], n * 3 - 2);
lines.push_back(temp);
}
return lines;
}
 
int main() {
for (int order = 1; order < 6; order++) {
int n = 1 << order;
auto points = getPointsForCurve(n);
std::cout << "Hilbert curve, order=" << order << '\n';
auto lines = drawCurve(points, n);
for (auto &line : lines) {
std::cout << line << '\n';
}
std::cout << '\n';
}
return 0;
}</syntaxhighlight>
{{out}}
<pre>Hilbert curve, order=1
 
|__|
 
Hilbert curve, order=2
__ __
__| |__
| __ |
|__| |__|
 
Hilbert curve, order=3
__ __ __ __
|__| __| |__ |__|
__ |__ __| __
| |__ __| |__ __| |
|__ __ __ __ __|
__| |__ __| |__
| __ | | __ |
|__| |__| |__| |__|
 
Hilbert curve, order=4
__ __ __ __ __ __ __ __ __ __
__| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__|
 
Hilbert curve, order=5
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
|__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__|
__ |__ __| __ | __ | __ |__ __| __ | __ | __ |__ __| __
| |__ __| |__ __| | |__| |__| | |__ __| |__ __| | |__| |__| | |__ __| |__ __| |
|__ __ __ __ __| __ __ | __ __ __ __ | __ __ |__ __ __ __ __|
__| |__ __| |__ | |__| | |__| __| |__ |__| | |__| | __| |__ __| |__
| __ | | __ | |__ __| __ |__ __| __ |__ __| | __ | | __ |
|__| |__| |__| |__| __| |__ __| |__ __| |__ __| |__ __| |__ |__| |__| |__| |__|
__ __ __ __ |__ __ __ __ __ __ __ __ __ __| __ __ __ __
| |__| | | |__| | __| |__ |__| __| |__ |__| __| |__ | |__| | | |__| |
|__ __| |__ __| | __ | __ |__ __| __ | __ | |__ __| |__ __|
__| |__ __ __| |__ |__| |__| | |__ __| |__ __| | |__| |__| __| |__ __ __| |__
| __ __ __ __ | __ __ | __ __ __ __ | __ __ | __ __ __ __ |
|__| __| |__ |__| | |__| | |__| __| |__ |__| | |__| | |__| __| |__ |__|
__ |__ __| __ |__ __| __ |__ __| __ |__ __| __ |__ __| __
| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |
|__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __|
__| |__ |__| __| |__ |__| __| |__ __| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ | | __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__| |__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __ __ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| | | |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __| |__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ | | __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __ __ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</pre>
 
=={{header|D}}==
{{trans|Java}}
<syntaxhighlight lang="d">import std.stdio;
 
void main() {
foreach (order; 1..6) {
int n = 1 << order;
auto points = getPointsForCurve(n);
writeln("Hilbert curve, order=", order);
auto lines = drawCurve(points, n);
foreach (line; lines) {
writeln(line);
}
writeln;
}
}
 
struct Point {
int x, y;
 
//rotate/flip a quadrant appropriately
void rot(int n, bool rx, bool ry) {
if (!ry) {
if (rx) {
x = (n - 1) - x;
y = (n - 1) - y;
}
 
import std.algorithm.mutation;
swap(x, y);
}
}
 
int calcD(int n) {
bool rx, ry;
int d;
for (int s = n >>> 1; s > 0; s >>>= 1) {
rx = ((x & s) != 0);
ry = ((y & s) != 0);
d += s * s * ((rx ? 3 : 0) ^ (ry ? 1 : 0));
rot(s, rx, ry);
}
return d;
}
 
void toString(scope void delegate(const(char)[]) sink) const {
import std.format : formattedWrite;
 
sink("(");
sink.formattedWrite!"%d"(x);
sink(", ");
sink.formattedWrite!"%d"(y);
sink(")");
}
}
 
auto fromD(int n, int d) {
Point p;
bool rx, ry;
int t = d;
for (int s = 1; s < n; s <<= 1) {
rx = ((t & 2) != 0);
ry = (((t ^ (rx ? 1 : 0)) & 1) != 0);
p.rot(s, rx, ry);
p.x += (rx ? s : 0);
p.y += (ry ? s : 0);
t >>>= 2;
}
return p;
}
 
auto getPointsForCurve(int n) {
Point[] points;
for (int d; d < n * n; ++d) {
points ~= fromD(n, d);
}
return points;
}
 
auto drawCurve(Point[] points, int n) {
import std.algorithm.comparison : min, max;
import std.array : uninitializedArray;
import std.exception : enforce;
 
auto canvas = uninitializedArray!(char[][])(n, n * 3 - 2);
foreach (line; canvas) {
line[] = ' ';
}
 
for (int i = 1; i < points.length; ++i) {
auto lastPoint = points[i - 1];
auto curPoint = points[i];
int deltaX = curPoint.x - lastPoint.x;
int deltaY = curPoint.y - lastPoint.y;
if (deltaX == 0) {
enforce(deltaY != 0, "Duplicate point");
// vertical line
int row = max(curPoint.y, lastPoint.y);
int col = curPoint.x * 3;
canvas[row][col] = '|';
} else {
enforce(deltaY == 0, "Diagonal line");
// horizontal line
int row = curPoint.y;
int col = min(curPoint.x, lastPoint.x) * 3 + 1;
canvas[row][col] = '_';
canvas[row][col + 1] = '_';
}
}
 
string[] lines;
foreach (row; canvas) {
lines ~= row.idup;
}
 
return lines;
}</syntaxhighlight>
{{out}}
<pre>Hilbert curve, order=1
 
|__|
 
Hilbert curve, order=2
__ __
__| |__
| __ |
|__| |__|
 
Hilbert curve, order=3
__ __ __ __
|__| __| |__ |__|
__ |__ __| __
| |__ __| |__ __| |
|__ __ __ __ __|
__| |__ __| |__
| __ | | __ |
|__| |__| |__| |__|
 
Hilbert curve, order=4
__ __ __ __ __ __ __ __ __ __
__| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__|
 
Hilbert curve, order=5
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
|__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__|
__ |__ __| __ | __ | __ |__ __| __ | __ | __ |__ __| __
| |__ __| |__ __| | |__| |__| | |__ __| |__ __| | |__| |__| | |__ __| |__ __| |
|__ __ __ __ __| __ __ | __ __ __ __ | __ __ |__ __ __ __ __|
__| |__ __| |__ | |__| | |__| __| |__ |__| | |__| | __| |__ __| |__
| __ | | __ | |__ __| __ |__ __| __ |__ __| | __ | | __ |
|__| |__| |__| |__| __| |__ __| |__ __| |__ __| |__ __| |__ |__| |__| |__| |__|
__ __ __ __ |__ __ __ __ __ __ __ __ __ __| __ __ __ __
| |__| | | |__| | __| |__ |__| __| |__ |__| __| |__ | |__| | | |__| |
|__ __| |__ __| | __ | __ |__ __| __ | __ | |__ __| |__ __|
__| |__ __ __| |__ |__| |__| | |__ __| |__ __| | |__| |__| __| |__ __ __| |__
| __ __ __ __ | __ __ | __ __ __ __ | __ __ | __ __ __ __ |
|__| __| |__ |__| | |__| | |__| __| |__ |__| | |__| | |__| __| |__ |__|
__ |__ __| __ |__ __| __ |__ __| __ |__ __| __ |__ __| __
| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |
|__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __|
__| |__ |__| __| |__ |__| __| |__ __| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ | | __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__| |__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __ __ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| | | |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __| |__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ | | __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __ __ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
This is a very fancy version of the Hilbert curve. It allows you to draw multiple levels and you have the option of superimposing each level on top of the others. You can choose four different pen colors that alternate according to the level. The pen thickness can vary according to the level and can be increments or decremented according to the settings.
 
<syntaxhighlight lang="Delphi">
 
procedure ClearBackground(Image: TImage; Color: TColor);
{Clear image with specified color}
begin
Image.Canvas.Brush.Color:=Color;
Image.Canvas.Pen.Color:=Color;
Image.Canvas.Rectangle(Image.ClientRect);
end;
 
{Array of colors used in display}
 
type TColorArray = array of TColor;
 
{Option controls the size of lines for each level}
 
type TPenMode = (pmNormal,pmIncrement,pmDecrement);
 
{Combined structure controls the Hilbert display}
 
type TCurveOptions = record
Order: integer;
SuperImposed: boolean;
PenMode: TPenMode;
ColorArray: TColorArray;
end;
 
 
procedure DrawHillbertCurve(Canvas: TCanvas; Width,Height: integer; Options: TCurveOptions);
{ Hilbert Curve}
var X,Y,X0,Y0,H,H0,StartX,StartY: double;
var I,Inx: integer;
 
procedure LeftUpRight(I: integer); forward;
procedure DownRightUp(I: integer); forward;
procedure RightDownLeft(I: integer); forward;
procedure UpLeftDown(I: integer); forward;
 
 
procedure DrawRealLine(var X,Y: double);
begin
Canvas.LineTo(Trunc(X),Trunc(Y));
end;
 
procedure LeftUpRight(I: integer);
begin
if I>0 then
begin
UpLeftDown(I-1);
X:=X-H;
DrawRealLine(X,Y);
LeftUpRight(I-1);
Y:=Y-H;
DrawRealLine(X,Y);
LeftUpRight(I-1);
X:=X+H;
DrawRealLine(X,Y);
DownRightUp(I-1);
end;
end;
 
procedure DownRightUp(I: integer);
begin
if I>0 then
begin
RightDownLeft(I-1);
Y:=Y+H;
DrawRealLine(X,Y);
DownRightUp(I-1);
X:=X+H;
DrawRealLine(X,Y);
DownRightUp(I-1);
Y:=Y-H;
DrawRealLine(X,Y);
LeftUpRight(I-1);
end;
end;
 
procedure RightDownLeft(I: integer);
begin
if I>0 then
begin
DownRightUp(I-1);
X:=X+H;
DrawRealLine(X,Y);
RightDownLeft(I-1);
Y:=Y+H;
DrawRealLine(X,Y);
RightDownLeft(I-1);
X:=X-H;
DrawRealLine(X,Y);
UpLeftDown(I-1);
end;
end;
 
procedure UpLeftDown(I: integer);
begin
if I>0 then
begin
LeftUpRight(I-1);
Y:=Y-H;
DrawRealLine(X,Y);
UpLeftDown(I-1);
X:=X-H;
DrawRealLine(X,Y);
UpLeftDown(I-1);
Y:=Y+H;
DrawRealLine(X,Y);
RightDownLeft(I-1);
end;
end;
 
begin
if Height<Width then H0:=Height else H0:=Width;
STARTX:=Width div 2;
STARTY:=Height div 2;
H:=H0;
X0:=STARTX;
Y0:=STARTY;
 
for I:=1 to Options.Order do
begin
case Options.PenMode of
pmDecrement: Canvas.Pen.Width:=(Options.Order - I) + 1;
pmIncrement: Canvas.Pen.Width:=I;
end;
Inx:=(I-1) mod Length(Options.ColorArray);
Canvas.Pen.Color:=Options.ColorArray[Inx];
H:=H / 2;
X0:=X0+(H / 2);
Y0:=Y0+(H / 2);
X:=X0;
Y:=Y0;
if not Options.SuperImposed and (Options.Order<>I) then continue;
Canvas.MoveTo(Trunc(X),Trunc(Y));
 
{ Draw Curve Of Order I }
LeftUpRight(I);
end;
end;
 
procedure ShowHilbertCurve(Image: TImage);
{Setup parameter and draw Hilbert curve on canvas}
var CA: TColorArray;
var Options: TCurveOptions;
begin
ClearBackground(Image,clWhite);
Image.Canvas.Pen.Width:=1;
SetLength(CA,4);
CA[0]:=clBlack;
CA[1]:=clGray;
CA[2]:=clSilver;
CA[3]:=clGray;
Options.Order:=5;
Options.SuperImposed:=True;
Options.PenMode:=pmNormal;
Options.ColorArray:=CA;
 
DrawHillbertCurve(Image.Canvas,Image.Width,Image.Height,Options);
end;
 
 
</syntaxhighlight>
{{out}}
[[File:DelphiHilbertCurve.png|thumb|none]]
<pre>
 
</pre>
 
=={{header|EasyLang}}==
 
{{trans|FutureBasic}}
 
[https://easylang.dev/show/#cod=jVBLDoIwEN33FG9JMSCtxp2HUajSpAFTUeH2zlAKRDa2TTPz5n2atr4yHmecjsLZxnxs1dU4aOzR8kQ8y4szNFdFETFkU5eENg2wFA/flqituxrfoccAd4dVsBo5cgHA3hgiM25ocWJ0ydBLsgp5MzbM2CTxpnv5hpvRcbSjq7JvaAaW+B1npzwcVnV4kiJru+XrhZ8EilyrtorAUvJXp/7S6ZUuZtMJDqzKRRQVtMOfUCW+ Run it]
 
<syntaxhighlight lang="easylang">
order = 64
linewidth 32 / order
scale = 100 / order - 100 / (order * order)
proc hilbert x y lg i1 i2 . .
if lg = 1
line (order - x) * scale (order - y) * scale
return
.
lg = lg div 2
hilbert x + i1 * lg y + i1 * lg lg i1 1 - i2
hilbert x + i2 * lg y + (1 - i2) * lg lg i1 i2
hilbert x + (1 - i1) * lg y + (1 - i1) * lg lg i1 i2
hilbert x + (1 - i2) * lg y + i2 * lg lg 1 - i1 i2
.
hilbert 0 0 order 0 0
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Hilbert curve. Nigel Galloway: September 18th., 2023
type C= |At|Cl|Ab|Cr
type D= |Z|U|D|L|R
let fD=function Z->0,0 |U->0,1 |D->0,-1 |L-> -1,0 |R->1,0
let fC=function At->[fD D;fD R;fD U] |Cl->[fD R;fD D;fD L] |Ab->[fD U;fD L;fD D] |Cr->[fD L;fD U;fD R]
let order(n,g)=match g with At->[n,Cl;D,At;R,At;U,Cr]
|Cl->[n,At;R,Cl;D,Cl;L,Ab]
|Ab->[n,Cr;U,Ab;L,Ab;D,Cl]
|Cr->[n,Ab;L,Cr;U,Cr;R,At]
let hilbert=Seq.unfold(fun n->Some(n,n|>List.collect order))[Z,At]
hilbert|>Seq.take 7|>Seq.iteri(fun n g->Chart.Line(g|>Seq.collect(fun(n,g)->(fD n)::(fC g))|>Seq.scan(fun(x,y)(n,g)->(x+n,y+g))(0,0))|>Chart.withTitle(sprintf "Hilbert order %d" n)|>Chart.show)
</syntaxhighlight>
{{out}}
[[File:Hilbert0.png]]
[[File:Hilbert1.png]]
[[File:Hilbert2.png]]
[[File:Hilbert3.png]]
[[File:Hilbert4.png]]
[[File:Hilbert5.png]]
[[File:Hilbert6.png]]
 
=={{header|Factor}}==
{{works with|Factor|0.99 2020-08-14}}
<syntaxhighlight lang="factor">USING: accessors L-system ui ;
 
: hilbert ( L-system -- L-system )
L-parser-dialect >>commands
[ 90 >>angle ] >>turtle-values
"A" >>axiom
{
{ "A" "-BF+AFA+FB-" }
{ "B" "+AF-BFB-FA+" }
} >>rules ;
 
[ <L-system> hilbert "Hilbert curve" open-window ] with-ui</syntaxhighlight>
 
 
When using the L-system visualizer, the following controls apply:
{| class="wikitable"
|+ Camera controls
|-
! Button !! Command
|-
| a || zoom in
|-
| z || zoom out
|-
| left arrow || turn left
|-
| right arrow || turn right
|-
| up arrow || pitch down
|-
| down arrow || pitch up
|-
| q || roll left
|-
| w || roll right
|}
{| class="wikitable"
|+ Other controls
|-
! Button !! Command
|-
| x || iterate L-system
|}
 
=={{header|Forth}}==
{{trans|Yabasic}}
{{works with|4tH|v3.62}}
<syntaxhighlight lang="forth">include lib/graphics.4th
 
64 constant /width \ Hilbert curve order^2
9 constant /length \ length of a line
 
variable origin \ point of origin
 
aka r@ lg \ get parameters from return stack
aka r'@ i1 \ so define some aliases
aka r"@ i2 \ to make it a bit more readable
 
: origin! 65536 * + origin ! ; ( n1 n2 --)
: origin@ origin @ 65536 /mod ; ( -- n1 n2)
 
: hilbert ( x y lg i1 i2 --)
>r >r >r lg 1 = if \ if lg equals 1
rdrop rdrop rdrop origin@ 2swap \ get point of origin
/width swap - /length * >r /width swap - /length * r>
2dup origin! line \ save origin and draw line
;then
 
r> 2/ >r \ divide lg by 2
over over i1 lg * tuck + >r + r> lg i1 1 i2 - hilbert
over over 1 i2 - lg * + swap i2 lg * + swap lg i1 i2 hilbert
over over 1 i1 - lg * tuck + >r + r> lg i1 i2 hilbert
i2 lg * + swap 1 i2 - lg * + swap r> 1 r> - r> hilbert
;
 
585 pic_width ! 585 pic_height ! \ set canvas size
color_image 255 whiteout blue \ paint blue on white
0 dup origin! \ set point of origin
0 dup /width over dup hilbert \ Hilbert curve, order=8
s" ghilbert.ppm" save_image \ save the image
</syntaxhighlight>
Output:
''Since Rosetta Code doesn't seem to support uploads anymore, the resulting file cannot be shown.''
 
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<syntaxhighlight lang="freebasic">
Dim Shared As Integer ancho = 64
 
Sub Hilbert(x As Integer, y As Integer, lg As Integer, i1 As Integer, i2 As Integer)
If lg = 1 Then
Line - ((ancho-x) * 10, (ancho-y) * 10)
Return
End If
lg = lg / 2
Hilbert(x+i1*lg, y+i1*lg, lg, i1, 1-i2)
Hilbert(x+i2*lg, y+(1-i2)*lg, lg, i1, i2)
Hilbert(x+(1-i1)*lg, y+(1-i1)*lg, lg, i1, i2)
Hilbert(x+(1-i2)*lg, y+i2*lg, lg, 1-i1, i2)
End Sub
 
Screenres 655, 655
 
Hilbert(0, 0, ancho, 0, 0)
End
</syntaxhighlight>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Hilbert_curve}}
 
'''Solution'''
 
=== Recursive ===
 
The following defines a function that creates a graphics of the Hilbert curve of a given order and size:
 
[[File:Fōrmulæ - Hilbert curve 01.png]]
 
'''Test cases'''
 
The following creates a table with Hilbert curves for orders 1 to 5:
 
[[File:Fōrmulæ - Hilbert curve 02.png]]
 
[[File:Fōrmulæ - Hilbert curve 03.png|279px]]
 
=== 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 Hilbert curve is:
 
[[File:Fōrmulæ - L-system - Hilbert curve 01.png]]
 
[[File:Fōrmulæ - L-system - Hilbert curve 02.png]]
 
=={{header|Frink}}==
This program generates arbitrary L-systems with slight modifications (see the commmented-out list of various angles and rules.)
<syntaxhighlight lang="frink">// General description:
// This code creates Lindenmayer rules via string manipulation
// It can generate many of the examples from the Wikipedia page
// discussing L-system fractals: http://en.wikipedia.org/wiki/L-system
//
// It does not support stochastic, context sensitive or parametric grammars
//
// It supports four special rules, and any number of variables in rules
// f = move forward one unit
// - = turn left one turn
// + = turn right one turn
// [ = save angle and position on a stack
// ] = restore angle and position from the stack
 
 
// The turn is how far each + or - in the final rule turns to either side
turn = 90 degrees
// This is how many times the rules get applied before we draw the result
times = 5
// This is our starting string
start = "++a"
// These are the rules we apply
rules = [["f","f"],["a","-bf+afa+fb-"], ["b","+af-bfb-fa+"]]
 
// L-System rules pulled from Wikipedia
// Dragon
// 90 degrees, "fx", [["f","f"],["x","x+yf"],["y","fx-y"]]
 
// TerDragon
// 120 degrees, "f", [["f","f+f-f"]]
 
// Koch curve
// 90 degrees, "f", [["f","f+f-f-f+f"]]
// use "++f" as the start to flip it over
 
// Sierpinski Triangle
// 60 degrees, "bf", [["f","f"],["a","bf-af-b"],["b","af+bf+a"]]
 
// Plant
// 25 degrees, "--x", [["f","ff"],["x","f-[[x]+x]+f[+fx]-x"]]
 
// Hilbert space filling curve
// 90 degrees, "++a", [["f","f"],["a","-bf+afa+fb-"], ["b","+af-bfb-fa+"]]
 
// Peano-Gosper curve
// 60 degrees, "x", [["f","f"],["x","x+yf++yf-fx--fxfx-yf+"], ["y","-fx+yfyf++yf+fx--fx-y"]]
 
// Lévy C curve
// 45 degrees, "f", [["f","+f--f+"]]
 
// This function will apply our rule once, using string substitutions based
// on the rules we pass it
// It does this in two passes to avoid problems with pairs of mutually referencing
// rules such as in the Sierpinski Triangle
// rules@k@1 could replace toString[k] and the entire second loop could
// vanish without adversely affecting the Dragon or Koch curves.
 
apply_rules[rules, current] :=
{
n = current
for k = 0 to length[rules]-1
{
rep = subst[rules@k@0,toString[k],"g"]
n =~ rep
}
for k = 0 to length[rules]-1
{
rep = subst[toString[k],rules@k@1,"g"]
n =~ rep
}
return n
}
 
// Here we will actually apply our rules the number of times specified
current = start
for i = 0 to times - 1
{
current = apply_rules[rules, current]
// Uncomment this line to see the string that is being produced at each stage
// println[current]
}
 
// Go ahead and plot the image now that we've worked it out
g = new graphics
g.antialiased[false] // Comment this out for non-square rules. It looks better
theta = 0 degrees
x = 0
y = 0
stack = new array
for i = 0 to length[current]-1
{
// This produces a nice sort of rainbow effect where most colors appear
// comment it out for a plain black fractal
// g.color[abs[sin[i degrees]],abs[cos[i*2 degrees]],abs[sin[i*4 degrees]]]
 
cur = substrLen[current,i,1]
if cur == "-"
theta = theta - (turn)
if cur == "+"
theta = theta + (turn)
if cur == "f" or cur == "F"
{
g.line[x,y,x + cos[theta],y + sin[theta]]
x = x + cos[theta]
y = y + sin[theta]
}
if cur == "["
stack.push[[theta,x,y]]
if cur == "]"
[theta,x,y] = stack.pop[]
}
 
g.show[]
g.write["hilbert.png",512,undef]
</syntaxhighlight>
 
=={{header|FutureBasic}}==
Hilbert Curve Order 64
<syntaxhighlight lang="futurebasic">
#define ORDER 64
 
_window = 1
 
void local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 651, 661 )
window _window, @"Order 64 Hilbert Curve In FutureBasic", r, NSWindowStyleMaskTitled
WindowSetBackgroundColor( _window, fn ColorBlack )
end fn
 
void local fn HilbertCurve( x as long, y as long, lg as long, i1 as long, i2 as long )
if ( lg == 1 )
line to ( ORDER-x ) * 10, ( ORDER-y ) * 10
exit fn
end if
lg = lg / 2
fn HilbertCurve( x+i1*lg, y+i1*lg, lg, i1, 1-i2 )
pen 2.0
fn HilbertCurve( x+i2*lg, y+(1-i2)*lg, lg, i1, i2 )
fn HilbertCurve( x+(1-i1)*lg, y+(1-i1)*lg, lg, i1, i2 )
fn HilbertCurve( x+(1-i2)*lg, y+i2*lg, lg, 1-i1, i2 )
end fn
 
fn BuildWindow
pen -2.0, fn ColorGreen
fn HilbertCurve( 0, 0, ORDER, 0, 0 )
 
HandleEvents
</syntaxhighlight>
{{output}}
[[File:Hilbert_Curve_FutureBasic.png]]
 
=={{header|Go}}==
Line 85 ⟶ 1,650:
<br>
The following is based on the recursive algorithm and C code in [https://www.researchgate.net/profile/Christoph_Schierz2/publication/228982573_A_recursive_algorithm_for_the_generation_of_space-filling_curves/links/0912f505c2f419782c000000/A-recursive-algorithm-for-the-generation-of-space-filling-curves.pdf this paper]. The image produced is similar to the one linked to in the zkl example.
<langsyntaxhighlight lang="go">package main
 
import "github.com/fogleman/gg"
Line 119 ⟶ 1,684:
dc.Stroke()
dc.SavePNG("hilbert.png")
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
{{Trans|Python}}
{{Trans|JavaScript}}
 
Defines an SVG string which can be rendered in a browser.
A Hilbert tree is defined in terms of a production rule,
and folded to a list of points in a square of given size.
 
<syntaxhighlight lang="haskell">import Data.Tree (Tree (..))
 
---------------------- HILBERT CURVE ---------------------
 
hilbertTree :: Int -> Tree Char
hilbertTree n
| 0 < n = iterate go seed !! pred n
| otherwise = seed
where
seed = Node 'a' []
go tree
| null xs = Node c (flip Node [] <$> rule c)
| otherwise = Node c (go <$> xs)
where
c = rootLabel tree
xs = subForest tree
 
 
hilbertPoints :: Int -> Tree Char -> [(Int, Int)]
hilbertPoints w = go r (r, r)
where
r = quot w 2
go r xy tree
| null xs = centres
| otherwise = concat $ zipWith (go d) centres xs
where
d = quot r 2
f g x = g xy + (d * g x)
centres =
((,) . f fst)
<*> f snd <$> vectors (rootLabel tree)
xs = subForest tree
 
 
--------------------- PRODUCTION RULE --------------------
 
rule :: Char -> String
rule c =
case c of
'a' -> "daab"
'b' -> "cbba"
'c' -> "bccd"
'd' -> "addc"
_ -> []
 
vectors :: Char -> [(Int, Int)]
vectors c =
case c of
'a' -> [(-1, 1), (-1, -1), (1, -1), (1, 1)]
'b' -> [(1, -1), (-1, -1), (-1, 1), (1, 1)]
'c' -> [(1, -1), (1, 1), (-1, 1), (-1, -1)]
'd' -> [(-1, 1), (1, 1), (1, -1), (-1, -1)]
_ -> []
 
 
--------------------------- TEST -------------------------
 
main :: IO ()
main = do
let w = 1024
putStrLn $ svgFromPoints w $ hilbertPoints w (hilbertTree 6)
 
svgFromPoints :: Int -> [(Int, Int)] -> String
svgFromPoints w xys =
let sw = show w
points =
(unwords . fmap (((<>) . show . fst) <*> ((' ' :) . show . snd))) xys
in unlines
[ "<svg xmlns=\"http://www.w3.org/2000/svg\"",
unwords
["width=\"512\" height=\"512\" viewBox=\"5 5", sw, sw, "\"> "],
"<path d=\"M" ++ points ++ "\" ",
"stroke-width=\"2\" stroke=\"red\" fill=\"transparent\"/>",
"</svg>"
]</syntaxhighlight>
 
=={{header|IS-BASIC}}==
<langsyntaxhighlight ISlang="is-BASICbasic">100 PROGRAM "Hilbert.bas"
110 OPTION ANGLE DEGREES
120 GRAPHICS HIRES 2
Line 139 ⟶ 1,788:
250 CALL HILBERT(S,N-1,-P)
260 PLOT LEFT 90*P;
270 END DEF</langsyntaxhighlight>
 
=={{header|J}}==
 
Note: J's {{ }} syntax requires a recent version of J (9.02 or more recent).
 
<syntaxhighlight lang="j">iter=: (, 1 , +@|.) @: (,~ 0j_1 ,~ 0j_1*|.)
hilbert=: {{0j1+(%{:) +/\0,iter ^: y ''}}
</syntaxhighlight>
 
For a graphical presentation, you could use (for example):
 
<syntaxhighlight lang="j">require'plot'
plot hilbert 5</syntaxhighlight>
 
For asciiart, you could instead use:
 
<syntaxhighlight lang="j">
asciiart=:{{
coords=. 1 3*"1 +. y % <./(,+.y)-.0
canvas=. (2+>./coords)$' '
pairs=. 2 ]\<.coords
horizontal=. =/"1 {."1 pairs
canvas=. '_' (0 1+"1<./"2 horizontal#pairs)} canvas
canvas=. '_' (0 2+"1<./"2 horizontal#pairs)} canvas
vertical=. -.horizontal
canvas=. '|' (>./"2 vertical#pairs)} canvas
}}
 
asciiart hilbert 4
__ __ __ __ __ __ __ __ __ __
|__ |__| __| |__ |__| __| |__ |__|
__| __ | __ | __ |__ __| __
|__ __| | |__| |__| | |__ __| |__ __| |
__ __ | __ __ |__ __ __ __ __|
|__ |__| | |__| | __| |__ __| |__
__| __ |__ __| | __ | | __ |
|__ __| |__ __| |__ |__| |__| |__| |__|
__ __ __ __ __| __ __ __ __
|__ |__| __| |__ | |__| | | |__| |
__| __ | __ | |__ __| |__ __|
|__ __| | |__| |__| __| |__ __ __| |__
__ __ | __ __ | __ __ __ __ |
|__ |__| | |__| | |__| __| |__ |__|
__| __ |__ __| __ |__ __| __
|__ __| |__ __| |__ __| |__ __| |__ __| | </syntaxhighlight>
 
The idea is to represent the nth order hilbert curve as list of complex numbers that can be summed to trace the curve. The 0th order hilbert curve is an empty list. The first half of the n+1 the curve is formed by rotating the nth right by 90 degrees and reversing, appending -i and appending the nth curve. The whole n+1th curve is the first half appended to 1 appended to the conjugate of the reverse of the first half.
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">// Translation from https://en.wikipedia.org/wiki/Hilbert_curve
 
import java.util.ArrayList;
Line 274 ⟶ 1,970:
return;
}
}</langsyntaxhighlight>
{{out}}
<pre>Hilbert curve, order=1
Line 353 ⟶ 2,049:
 
An implementation of GO. Prints an SVG string that can be read in a browser.
<langsyntaxhighlight lang="javascript">const hilbert = (width, spacing, points) => (x, y, lg, i1, i2, f) => {
if (lg === 1) {
const px = (width - x) * spacing;
Line 406 ⟶ 2,102:
};
 
drawHilbert(6);</langsyntaxhighlight>
 
===Functional===
{{Trans|Python}}
 
A composition of generic pure functions which defines a Hilbert tree as the Nth application of a production rule to a seedling tree.
 
A list of points is derived by serialization of that tree.
Line 417 ⟶ 2,113:
Like the version above, generates an SVG string for display in a browser.
 
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'"use strict'";
 
// ------------------ HILBERT CURVE ------------------
const main = () => {
 
// rulehilbertCurve :: Dict Char [Char(Int, Int)] ->
// Dict Char [Char] -> Int -> Int -> SVG string
const rule = {
const hilbertCurve = dictVector =>
a: ['d', 'a', 'a', 'b'],
dictRule => width => b: ['c', 'b', 'b', 'a'],compose(
c: ['b', 'c', 'c', 'd']svgFromPoints(width),
d: ['a'hilbertPoints(dictVector)(width), 'd', 'd', 'c']
hilbertTree(dictRule)
);
 
 
// hilbertTree :: Dict Char [Char] -> Int -> Tree Char
const hilbertTree = rule =>
n => {
const go = tree => {
const xs = tree.nest;
 
return Node(tree.root)(
0 < xs.length
? xs.map(go)
: rule[tree.root].map(
flip(Node)([])
)
);
};
const seed = Node("a")([]);
 
return 0 < n
? take(n)(
iterate(go)(seed)
)
.slice(-1)[0]
: seed;
};
 
 
// vectors :: Dict Char [(Int, Int)]
// hilbertPoints :: Size const-> vectorsTree =Char -> [({x, y)]
// hilbertPoints :: Int -> Tree Char 'a':-> [(Int, Int)]
const hilbertPoints = dict =>
w => tree => {
const go = d => (xy, t) => {
const
r = Math.floor(d / 2),
centres = dict[t.root]
.map(v => [
xy[0] + (r * v[0]),
xy[1] + (r * v[1])
]);
 
return 0 < t.nest.length
? zipWith(
go(r)
)(centres)(t.nest).flat()
: centres;
};
const d = Math.floor(w / 2);
 
return go(d)([d, d], tree);
};
 
 
// svgFromPoints :: Int -> [(Int, Int)] -> String
const svgFromPoints = w => xys => [
"<svg xmlns=\"http://www.w3.org/2000/svg\"",
`width="500" height="500" viewBox="5 5 ${w} ${w}">`,
`<path d="M${(xys).flat().join(" ")}" `,
// eslint-disable-next-line quotes
'stroke-width="2" stroke="red" fill="transparent"/>',
"</svg>"
].join("\n");
 
 
// -------------------- TEST ---------------------
const main = () =>
hilbertCurve({
"a": [
[-1, 1],
[-1, -1],
Line 438 ⟶ 2,198:
[1, 1]
],
'"b'": [
[1, -1],
[-1, -1],
Line 444 ⟶ 2,204:
[1, 1]
],
'"c'": [
[1, -1],
[1, 1],
Line 450 ⟶ 2,210:
[-1, -1]
],
'"d'": [
[-1, 1],
[1, 1],
Line 456 ⟶ 2,216:
[-1, -1]
]
});({
a: ["d", "a", "a", "b"],
b: ["c", "b", "b", "a"],
c: ["b", "c", "c", "d"],
d: ["a", "d", "d", "c"]
})(1024)(6);
 
// hilbertCurve :: Int -> SVG string
const hilbertCurve = n => {
const w = 1024
return svgFromPoints(w)(
hilbertPoints(w)(
hilbertTree(n)
)
);
}
 
// ---------------- GENERIC FUNCTIONS ----------------
// hilbertTree :: Int -> Tree Char
const hilbertTree = n => {
const go = tree =>
Node(
tree.root,
0 < tree.nest.length ? (
map(go, tree.nest)
) : map(x => Node(x, []), rule[tree.root])
);
const seed = Node('a', []);
return 0 < n ? (
take(n, iterate(go, seed)).slice(-1)[0]
) : seed;
};
 
// hilbertPointsNode :: Sizea -> [Tree Chara] -> [(x,Tree y)]a
const Node = v =>
// hilbertPoints :: Int -> Tree Char -> [(Int, Int)]
const// hilbertPointsConstructor =for wa =>Tree treenode =>which {connects a
// value of some constkind goto =a dlist =>of (xy,zero tree) => {or
// more child consttrees.
rxs => Math.floor(d / 2),{
type: centres = map("Node",
root: v => [,
nest: xs || xy[0] + (r * v[0]),
});
xy[1] + (r * v[1])
],
vectors[tree.root]
);
return 0 < tree.nest.length ? concat(
zipWith(go(r), centres, tree.nest)
) : centres;
};
const d = Math.floor(w / 2);
return go(d)([d, d], tree);
};
 
// svgFromPoints :: Int -> [(Int, Int)] -> String
const svgFromPoints = w => xys => ['<svg xmlns="http://www.w3.org/2000/svg"',
`width="500" height="500" viewBox="5 5 ${w} ${w}">`,
`<path d="M${concat(xys).join(' ')}" `,
'stroke-width="2" stroke="red" fill="transparent"/>',
'</svg>'
].join('\n');
 
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
// TEST -------------------------------------------
const compose = (...fs) =>
console.log(
// A function defined by the right-to-left
hilbertCurve(6)
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
};
 
// GENERIC FUNCTIONS ----------------------------------
 
// Nodeflip :: (a -> [Treeb a]-> c) -> Treeb -> a -> c
const Nodeflip = (v, xs)op => ({
// The binary function type:op 'Node',with
// its arguments reversed.
root: v, // any type of value (consistent across tree)
nest:1 xs!== || []op.length
? (a, b) => op(b, a)
});
: (a => b => op(b)(a));
 
// concat :: [[a]] -> [a]
// concat :: [String] -> String
const concat = xs =>
0 < xs.length ? (() => {
const unit = 'string' !== typeof xs[0] ? (
[]
) : '';
return unit.concat.apply(unit, xs);
})() : [];
 
// iterate :: (a -> a) -> a -> Gen [a]
function*const iterate(f, x)= f {=>
let// vAn =infinite x;list of repeated applications
// of f, starting with the seed value x.
while (true) {
function* yield(vx); {
let v = f(v)x;
 
}
while (true) {
}
yield v;
v = f(v);
}
};
 
// 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
 
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
(Array.isArray(xs) || 'string' === typeof xs) ? (
// length. This enables xs.lengthzip and zipWith to choose
// the shorter argument when one is non-finite,
) : Infinity;
// like cycle, repeat etc
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
 
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) =>
(Array.isArray(xs) ? (
xs
) : xs.split('')).map(f);
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
// The first n elements of a list,
'GeneratorFunction' !== xs.constructor.constructor.name ? (
// string of xs.slice(0characters, n)or stream.
)xs :=> [].concat.apply([],"GeneratorFunction" Array.from({!== xs
.constructor.constructor.name ? (
length: n
}, () => { xs.slice(0, n)
const) x: = xsArray.nextfrom();{
return x.done ? [] length: [x.value];n
}, ()); => {
const x = xs.next();
 
return x.done ? [] : [x.value];
}).flat();
 
// Use of `take` and `length` here allows zipping with non-finite lists
// i.e. generators like cycle, repeat, iterate.
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = (f, xs, ys) => {
constxs => ys => {
lng = Math.min(length(xs), length(ys)),const
as n = takeMath.min(lnglength(xs), xslength(ys)),
bs as = take(lng, ysn);(xs),
return Array.from bs = take(n)({ys);
 
length: lng
}, (_, i) => freturn Array.from(as[i], bs[i], i));{
length: n
};
}, (_, i) => f(as[i], bs[i]));
};
 
 
// MAIN ---
return main();
})();</langsyntaxhighlight>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
The program given here generates SVG code that can be
viewed directly in a browser, at least if the file suffix is .svg.
 
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:
{ A: "-BF+AFA+FB-",
B: "+AF-BFB-FA+" };
 
def hilbert($count):
rules as $rules
| def p($count):
if $count <= 0 then .
else gsub("A"; "a") | gsub("B"; $rules["B"]) | gsub("a"; $rules["A"])
| p($count-1)
end;
"A" | p($count) ;
 
def interpret($x):
if $x == "+" then turtleRotate(90)
elif $x == "-" then turtleRotate(-90)
elif $x == "F" then turtleForward(5)
else .
end;
 
def hilbert_curve($n):
hilbert($n)
| split("")
| reduce .[] as $action (turtle([0,5]) | turtleDown;
interpret($action) ) ;
 
hilbert_curve(5)
| path("none"; "red"; 1) | svg(170)
</syntaxhighlight>
{{out}}
https://imgur.com/a/mJAaY6I
 
=={{header|Julia}}==
Color graphics version using the Gtk package.
<langsyntaxhighlight lang="julia">using Gtk, Graphics, Colors
 
Base.isless(p1::Vec2, p2::Vec2) = (p1.x == p2.x ? p1.y < p2.y : p1.x < p2.x)
Line 677 ⟶ 2,447:
signal_connect(endit, win, :destroy)
wait(cond)
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 683 ⟶ 2,453:
 
The coordinates of the points are generated using a translation of the C code in the Wikipedia article and then scaled by a factor of 3 (n = 32).
<langsyntaxhighlight lang="scala">// Version 1.2.40
 
data class Point(var x: Int, var y: Int)
Line 748 ⟶ 2,518:
println()
}
}</langsyntaxhighlight>
 
{{output}}
Line 845 ⟶ 2,615:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
.__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. .__. </pre>
 
=={{header|Lambdatalk}}==
 
The output is visible in [http://lambdaway.free.fr/lambdawalks/?view=hilbert Hibert curve]
 
<syntaxhighlight lang="scheme">
1) two twinned recursive functions
 
{def left {lambda {:d :n}
{if {< :n 1}
then
else T90 {right :d {- :n 1}}
M:d T-90 {left :d {- :n 1}}
M:d {left :d {- :n 1}}
T-90 M:d {right :d {- :n 1}}
T90}}}
 
{def right {lambda {:d :n}
{if {< :n 1}
then
else T-90 {left :d {- :n 1}}
M:d T90 {right :d {- :n 1}}
M:d {right :d {- :n 1}}
T90 M:d {left :d {- :n 1}}
T-90}}}
 
The word Tθ rotates the drawing direction of a pen from θ degrees and the word Md moves it on d pixels.
 
{def H5 {left 18 5}}
 
The call {def H5 {left 18 5}} produces 2387 words begining with [T90 T-90 T90 T-90 T90 M10 T-90 M10 T-90 M10 T90 M10 T90 T-90 M10 T90 M10 T90 M10 T-90 M10 T-90 M10 T90 M10 T90 M10 T-90 T90 M10 T90 M10 T-90 M10 T-90 ...]
 
2) the SVG context
 
Lambdatalk comes with a primitive, turtle, translating the previous sequence of words into a sequence of SVG points [x0 y0 x1 y2 ... xn yn] feeding the "d" attribute of a SVG path.
 
{def stroke
{lambda {:w :c}
fill="transparent" stroke=":c" stroke-width=":w"}}
 
{svg
{@ width="580px" height="580px"}
{path {@ d="M {turtle 10 10 0 {H5}}" {stroke 8 #000}}}
{path {@ d="M {turtle 10 10 0 {H5}}" {stroke 4 #000}}}
{path {@ d="M {turtle 10 10 0 {H5}}" {stroke 1 #fff}}}
}
</syntaxhighlight>
 
=={{header|Lua}}==
Line 863 ⟶ 2,680:
* <num> repeat the following draw command <num> times
* <any> move on canvas without drawing
<langsyntaxhighlight lang="lua">-- any version from LuaJIT 2.0/5.1, Lua 5.2, Lua 5.3 to LuaJIT 2.1.0-beta3-readline
local bit=bit32 or bit -- Lua 5.2/5.3 compatibilty
-- Hilbert curve implemented by Lindenmayer system
Line 950 ⟶ 2,767:
local str=arg[2] or "A"
draw(str:hilbert(n))
</syntaxhighlight>
</lang>
{{output}} luajit hilbert.lua 4 1M9FAF-4F2+2F-2F-2F++4F-F-4F+2F+2F+2F++3F+2F+3F--4FA10F-16F-58F-16F-
<pre>
Line 972 ⟶ 2,789:
 
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
'''Works with:''' Mathematica 11
<syntaxhighlight lang="mathematica">Graphics@HilbertCurve[4]</syntaxhighlight>
 
=={{header|Nim}}==
{{trans|Algol68}}
<syntaxhighlight lang="nim">const
Level = 4
Side = (1 shl Level) * 2 - 2
 
type Direction = enum E, N, W, S
 
const
 
# Strings to use according to direction.
Drawings1: array[Direction, string] = ["──", " │", "──", " │"]
 
# Strings to use according to old and current direction.
Drawings2: array[Direction, array[Direction, string]] = [["──", "─╯", " ?", "─╮"],
[" ╭", " │", "─╮", " ?"],
[" ?", " ╰", "──", " ╭"],
[" ╰", " ?", "─╯", " │"]]
 
type Curve = object
grid: array[-Side..1, array[0..Side, string]]
x, y: int
dir, oldDir: Direction
 
proc newCurve(): Curve =
## Create a new curve.
result.x = 0
result.y = 0
result.dir = E
result.oldDir = E
for row in result.grid.mitems:
for item in row.mitems:
item = " "
 
proc left(dir: var Direction) =
## Turn on the left.
dir = if dir == S: E else: succ(dir)
 
proc right(dir: var Direction) =
## Turn on the right.
dir = if dir == E: S else: pred(dir)
 
proc move(curve: var Curve) =
## Move to next position according to current direction.
case curve.dir
of E: inc curve.x
of N: dec curve.y
of W: dec curve.x
of S: inc curve.y
 
proc forward(curve: var Curve) =
# Do one step: draw a corner, draw a segment and advance to next corner.
 
# Draw corner.
curve.grid[curve.y][curve.x] = Drawings2[curve.oldDir][curve.dir]
curve.move()
 
# Draw segment.
curve.grid[curve.y][curve.x] = Drawings1[curve.dir]
 
# Advance to next corner.
curve.move()
curve.oldDir = curve.dir
 
# Forward reference.
proc b(curve: var Curve; level: int)
 
proc a(curve: var Curve; level: int) =
## "A" function.
if level > 0:
curve.dir.left()
curve.b(level - 1)
curve.forward()
curve.dir.right()
curve.a(level - 1)
curve.forward()
curve.a(level - 1)
curve.dir.right()
curve.forward()
curve.b(level - 1)
curve.dir.left()
 
proc b(curve: var Curve; level: int) =
## "B" function.
if level > 0:
curve.dir.right()
curve.a(level - 1)
curve.forward()
curve.dir.left()
curve.b(level - 1)
curve.forward()
curve.b(level - 1)
curve.dir.left()
curve.forward()
curve.a(level - 1)
curve.dir.right()
 
### Main code
 
var curve = newCurve()
 
# Draw.
curve.a(Level)
 
# Print.
for row in curve.grid:
for s in row:
stdout.write(s)
stdout.writeLine("")
</syntaxhighlight>
{{out}}
See Algol68 version.
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use SVG;
use List::Util qw(max min);
 
Line 1,013 ⟶ 2,947:
open $fh, '>', 'hilbert_curve.svg';
print $fh $svg->xmlify(-namespace=>'svg');
close $fh;</langsyntaxhighlight>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/hilbert_curve.svg Hilbert curve] (offsite image)
 
=={{header|Perl 6Phix}}==
{{trans|Go}}
{{works with|Rakudo|2018.03}}
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/hilbert_curve.htm here].
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\hilbert_curve.exw
-- ==============================
--
-- Draws a hilbert curve.
--</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Hilbert Curve"</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">width</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">64</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">px</span> <span style="color: #0000FF;">:=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">py</span> <span style="color: #0000FF;">:=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">10</span>
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">py</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">lg</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">2</span>
<span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i2</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i2</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<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>
<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;">cdCanvasBegin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_OPEN_LINES</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">cdCanvasEnd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<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>
<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_WHITE</span><span style="color: #0000FF;">)</span>
<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: #004600;">CD_MAGENTA</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">hilbert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</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: #008000;">"RASTERSIZE=655x655"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</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: #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;">`TITLE="%s"`</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
<span style="color: #000080;font-style:italic;">-- no resize here (since width is the constant 64...)</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;">"DIALOGFRAME"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"YES"</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|Processing}}==
<lang perl6>use SVG;
 
<syntaxhighlight lang="java">int iterations = 7;
role Lindenmayer {
float strokeLen = 600;
has %.rules;
int angleDeg = 90;
method succ {
String axiom = "L";
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
StringDict rules = new StringDict();
}
String sentence = axiom;
int xo, yo;
 
void setup() {
size(700, 700);
xo= 50;
yo = height - 50;
strokeWeight(1);
noFill();
rules.set("L", "+RF-LFL-FR+");
rules.set("R", "-LF+RFR+FL-");
generate(iterations);
}
 
void draw() {
my $hilbert = 'A' but Lindenmayer( { A => '-BF+AFA+FB-', B => '+AF-BFB-FA+' } );
background(0);
translate(xo, yo);
plot(radians(angleDeg));
}
 
void generate(int n) {
$hilbert++ xx 7;
for (int i=0; i < n; i++) {
my @points = (647, 13);
strokeLen *= 0.5;
 
String nextSentence = "";
for $hilbert.comb {
for (int j=0; j < sentence.length(); j++) {
state ($x, $y) = @points[0,1];
state $d =char -5c -= 0isentence.charAt(j);
String ruleResult = rules.get(str(c), str(c));
when 'F' { @points.append: ($x += $d.re).round(1), ($y += $d.im).round(1) }
nextSentence += ruleResult;
when /< + - >/ { $d *= "{$_}1i" }
default { }
sentence = nextSentence;
}
}
 
void plot(float angle) {
say SVG.serialize(
for (int i=0; i < sentence.length(); i++) {
svg => [
char c = sentence.charAt(i);
:660width, :660height, :style<stroke:blue>,
if (c == 'F') {
:rect[:width<100%>, :height<100%>, :fill<white>],
stroke(255);
:polyline[ :points(@points.join: ','), :fill<white> ],
line(0, 0, 0, -strokeLen);
],
translate(0, -strokeLen);
);</lang>
} else if (c == '+') {
See: [https://github.com/thundergnat/rc/blob/master/img/hilbert-perl6.svg Hilbert curve]
rotate(angle);
 
} else if (c == '-') {
There is a variation of a Hilbert curve known as a [[wp:Moore curve|Moore curve]] which is essentially 4 Hilbert curves joined together in a loop.
rotate(-angle);
<lang perl6>use SVG;
 
role Lindenmayer {
has %.rules;
method succ {
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
}
}
}
 
void keyPressed() {
my $moore = 'AFA+F+AFA' but Lindenmayer( { A => '-BF+AFA+FB-', B => '+AF-BFB-FA+' } );
if (key == '-') {
angleDeg -= 1;
println("Angle: " + angleDeg);
}
if (key == '=' || key == '+') {
angleDeg += 1;
println("Angle: " + angleDeg);
}
if (key == 'a') {
strokeLen *= 2;
}
if (key == 'z') {
strokeLen /= 2;
}
if (keyCode == LEFT) {
xo -= 25;
}
if (keyCode == RIGHT) {
xo += 25;
}
if (keyCode == UP) {
yo -= 25;
}
if (keyCode == DOWN) {
yo += 25;
}
}</syntaxhighlight>
 
==={{header|Processing Python mode}}===
$moore++ xx 6;
my @points = (327, 647);
 
<syntaxhighlight lang="python">iterations = 7
for $moore.comb {
stroke_len = 600
state ($x, $y) = @points[0,1];
angle_deg = 90
state $d = 0 - 5i;
axiom = 'L'
when 'F' { @points.append: ($x += $d.re).round(1), ($y += $d.im).round(1) }
sentence = axiom
when /< + - >/ { $d *= "{$_}1i" }
rules = {
default { }
'L': '+RF-LFL-FR+',
'R': '-LF+RFR+FL-',
}
 
def setup():
say SVG.serialize(
svgsize(700, => [700)
global xo, yo
:660width, :660height, :style<stroke:darkviolet>,
xo, yo = :rect[:width<100%>50, :height<100%>, :fill<white>],- 50
strokeWeight(1)
:polyline[ :points(@points.join: ','), :fill<white> ],
],noFill()
generate(iterations)
);</lang>
See: [https://github.com/thundergnat/rc/blob/master/img/moore-perl6.svg Moore curve]
 
def draw():
=={{header|Phix}}==
background(0)
{{trans|Go}}
translate(xo, yo)
<lang Phix>-- demo\rosetta\hilbert_curve.exw
plot(radians(angle_deg))
include pGUI.e
 
def generate(n):
Ihandle dlg, canvas
global stroke_len, sentence
cdCanvas cddbuffer, cdcanvas
for _ in range(n):
stroke_len *= 0.5
next_sentence = ''
for c in sentence:
next_sentence += rules.get(c, c)
sentence = next_sentence
 
def plot(angle):
constant width = 64
for c in sentence:
if c == 'F':
stroke(255)
line(0, 0, 0, -stroke_len)
translate(0, -stroke_len)
elif c == '+':
rotate(angle)
elif c == '-':
rotate(-angle)
 
def keyPressed():
sequence points = {}
global angle_deg, xo, yo, stroke_len
 
if key == '-':
procedure hilbert(integer x, y, lg, i1, i2)
if lg angle_deg -=1 then5
integer px := print(width-xangle_deg) * 10,
if py := str(width-ykey) *in 10"=+":
pointsangle_deg += append(points, {px, py})5
returnprint(angle_deg)
end if key == 'a':
lg / stroke_len *= 2
if key == 'z':
hilbert(x+i1*lg, y+i1*lg, lg, i1, 1-i2)
stroke_len /= 2
hilbert(x+i2*lg, y+(1-i2)*lg, lg, i1, i2)
if keyCode == LEFT:
hilbert(x+(1-i1)*lg, y+(1-i1)*lg, lg, i1, i2)
xo -= 50
hilbert(x+(1-i2)*lg, y+i2*lg, lg, 1-i1, i2)
if keyCode == RIGHT:
end procedure
xo += 50
 
if keyCode == UP:
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
yo -= 50
cdCanvasActivate(cddbuffer)
if keyCode == DOWN:
cdCanvasBegin(cddbuffer, CD_OPEN_LINES)
yo += 50</syntaxhighlight>
for i=1 to length(points) do
integer {x,y} = points[i]
cdCanvasVertex(cddbuffer, x, y)
end for
cdCanvasEnd(cddbuffer)
cdCanvasFlush(cddbuffer)
return IUP_DEFAULT
end function
 
function map_cb(Ihandle ih)
cdcanvas = cdCreateCanvas(CD_IUP, ih)
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
cdCanvasSetBackground(cddbuffer, CD_WHITE)
cdCanvasSetForeground(cddbuffer, CD_MAGENTA)
return IUP_DEFAULT
end function
 
procedure main()
hilbert(0, 0, width, 0, 0)
IupOpen()
canvas = IupCanvas(NULL)
IupSetAttribute(canvas, "RASTERSIZE", "655x655")
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
dlg = IupDialog(canvas)
IupSetAttribute(dlg, "TITLE", "Hilbert Curve")
IupSetAttribute(dlg, "DIALOGFRAME", "YES") -- no resize here
IupCloseOnEscape(dlg)
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
IupMap(dlg)
IupShowXY(dlg,IUP_CENTER,IUP_CENTER)
IupMainLoop()
IupClose()
end procedure
main()</lang>
 
=={{header|Python}}==
===Functional===
 
Composition of pure functions, with type comments for the reader rather than the compiler.
 
Line 1,154 ⟶ 3,187:
(To view the Hilbert curve, save the output SVG text in a file with an appropriate extension (e.g. '''.svg'''), and open it with a browser).
 
{{Works with|Python|3.7}}
<lang Python>from itertools import (chain, islice, starmap)
<syntaxhighlight lang="python">'''Hilbert curve'''
 
from itertools import (chain, islice)
# rule :: Dict Char [Char]
rule = {
'a': ['d', 'a', 'a', 'b'],
'b': ['c', 'b', 'b', 'a'],
'c': ['b', 'c', 'c', 'd'],
'd': ['a', 'd', 'd', 'c']
}
 
# vectors :: Dict Char [(Int, Int)]
vectors = {
'a': [(-1, 1), (-1, -1), (1, -1), (1, 1)],
'b': [(1, -1), (-1, -1), (-1, 1), (1, 1)],
'c': [(1, -1), (1, 1), (-1, 1), (-1, -1)],
'd': [(-1, 1), (1, 1), (1, -1), (-1, -1)]
}
 
 
# hilbertCurve :: Int -> SVG String
def hilbertCurve(n):
'''An SVG string representing a
Hilbert curve of degree n.
'''
w = 1024
return svgFromPoints(w)(
Line 1,185 ⟶ 3,208:
# hilbertTree :: Int -> Tree Char
def hilbertTree(n):
'''Nth application of a rule to a tree seedling tree.'''
 
# rule :: Dict Char [Char]
rule = {
'a': ['d', 'a', 'a', 'b'],
'b': ['c', 'b', 'b', 'a'],
'c': ['b', 'c', 'c', 'd'],
'd': ['a', 'd', 'd', 'c']
}
 
# go :: Tree Char -> Tree Char
Line 1,205 ⟶ 3,236:
# hilbertPoints :: Int -> Tree Char -> [(Int, Int)]
def hilbertPoints(w):
'''Serialization of a tree to a list of points in a square of side w'''
bounded by a square of side w.
'''
 
# vectors :: Dict Char [(Int, Int)]
vectors = {
'a': [(-1, 1), (-1, -1), (1, -1), (1, 1)],
'b': [(1, -1), (-1, -1), (-1, 1), (1, 1)],
'c': [(1, -1), (1, 1), (-1, 1), (-1, -1)],
'd': [(-1, 1), (1, 1), (1, -1), (-1, -1)]
}
 
# points :: Int -> ((Int, Int), Tree Char) -> [(Int, Int)]
def points(d):
'''Size -> Centre of a Hilbert subtree -> All subtree points'''
'''
def go(xy, tree):
r = d // 2
 
centres = map(
def lambda deltas(v): (
return (
xy[0] + (r * v[0]),
xy[1] + (r * v[1])
),
centres = map(deltas, vectors[tree['root']])
)
return chain.from_iterable(
starmapmap(points(r), zip(centres, tree['nest']))
) if tree['nest'] else centres
return lambda xy, tree: go(xy, tree)
 
d = w // 2
Line 1,232 ⟶ 3,274:
'''Width of square canvas -> Point list -> SVG string'''
 
def go(w, xys):
xsdef = ' '.join(mappoints(xy):
lambda xy:return str(xy[0]) + ' ' + str(xy[1]),
xs = ' '.join(map(points, xys))
))
return '\n'.join(
['<svg xmlns="http://www.w3.org/2000/svg"',
Line 1,245 ⟶ 3,286:
]
)
return lambda xys: go(w, xys)
 
 
# GENERIC FUNCTIONS ------------------------- TEST --------------------------
def main():
'''Testing generation of the SVG for a Hilbert curve'''
print(
hilbertCurve(6)
)
 
 
# ------------------- GENERIC FUNCTIONS -------------------
 
# Node :: a -> [Tree a] -> Tree a
def Node(v):
'''Contructor for a Tree node which connects a
return lambda xs: {
value 'type':of 'Node',some 'root':kind v,to 'nest':a xslist of zero or
more child trees.'''
}
return lambda xs: {'type': 'Node', 'root': v, 'nest': xs}
 
 
# flip :: (a -> b -> c) -> b -> a -> c
def flip(f):
'''The (curried or uncurried) function f with its
arguments reversed.
'''
return lambda a: lambda b: f(b)(a)
 
Line 1,265 ⟶ 3,317:
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield( v)
v = f(v)
return lambda x: go(x)
 
 
# TEST ---------------------------------------------------
if __name__ == '__main__':
main()</syntaxhighlight>
print (
 
hilbertCurve(6)
===Recursive===
)</lang>
<syntaxhighlight lang="python">
import matplotlib.pyplot as plt
import numpy as np
import turtle as tt
 
# dictionary containing the first order hilbert curves
base_shape = {'u': [np.array([0, 1]), np.array([1, 0]), np.array([0, -1])],
'd': [np.array([0, -1]), np.array([-1, 0]), np.array([0, 1])],
'r': [np.array([1, 0]), np.array([0, 1]), np.array([-1, 0])],
'l': [np.array([-1, 0]), np.array([0, -1]), np.array([1, 0])]}
 
 
def hilbert_curve(order, orientation):
"""
Recursively creates the structure for a hilbert curve of given order
"""
if order > 1:
if orientation == 'u':
return hilbert_curve(order - 1, 'r') + [np.array([0, 1])] + \
hilbert_curve(order - 1, 'u') + [np.array([1, 0])] + \
hilbert_curve(order - 1, 'u') + [np.array([0, -1])] + \
hilbert_curve(order - 1, 'l')
elif orientation == 'd':
return hilbert_curve(order - 1, 'l') + [np.array([0, -1])] + \
hilbert_curve(order - 1, 'd') + [np.array([-1, 0])] + \
hilbert_curve(order - 1, 'd') + [np.array([0, 1])] + \
hilbert_curve(order - 1, 'r')
elif orientation == 'r':
return hilbert_curve(order - 1, 'u') + [np.array([1, 0])] + \
hilbert_curve(order - 1, 'r') + [np.array([0, 1])] + \
hilbert_curve(order - 1, 'r') + [np.array([-1, 0])] + \
hilbert_curve(order - 1, 'd')
else:
return hilbert_curve(order - 1, 'd') + [np.array([-1, 0])] + \
hilbert_curve(order - 1, 'l') + [np.array([0, -1])] + \
hilbert_curve(order - 1, 'l') + [np.array([1, 0])] + \
hilbert_curve(order - 1, 'u')
else:
return base_shape[orientation]
 
 
# test the functions
if __name__ == '__main__':
order = 8
curve = hilbert_curve(order, 'u')
curve = np.array(curve) * 4
cumulative_curve = np.array([np.sum(curve[:i], 0) for i in range(len(curve)+1)])
# plot curve using plt
plt.plot(cumulative_curve[:, 0], cumulative_curve[:, 1])
# draw curve using turtle graphics
tt.setup(1920, 1000)
tt.pu()
tt.goto(-950, -490)
tt.pd()
tt.speed(0)
for item in curve:
tt.goto(tt.pos()[0] + item[0], tt.pos()[1] + item[1])
tt.done()
</syntaxhighlight>
 
=={{header|QB64}}==
{{trans|YaBASIC}}
<syntaxhighlight lang="qb64">_Title "Hilbert Curve"
Dim Shared As Integer sw, sh, wide, cell
 
wide = 128: cell = 4
sw = wide * cell + cell
sh = sw
 
Screen _NewImage(sw, sh, 8)
Cls , 15: Color 0
PSet (wide * cell, wide * cell)
 
Call Hilbert(0, 0, wide, 0, 0)
 
Sleep
System
 
Sub Hilbert (x As Integer, y As Integer, lg As Integer, p As Integer, q As Integer)
Dim As Integer iL, iX, iY
iL = lg: iX = x: iY = y
If iL = 1 Then
Line -((wide - iX) * cell, (wide - iY) * cell)
Exit Sub
End If
iL = iL \ 2
Call Hilbert(iX + p * iL, iY + p * iL, iL, p, 1 - q)
Call Hilbert(iX + q * iL, iY + (1 - q) * iL, iL, p, q)
Call Hilbert(iX + (1 - p) * iL, iY + (1 - p) * iL, iL, p, q)
Call Hilbert(iX + (1 - q) * iL, iY + q * iL, iL, 1 - p, q)
End Sub</syntaxhighlight>
 
=={{header|Quackery}}==
 
Using an L-system. (Described at [[L-system#Quackery]].)
 
<syntaxhighlight lang="quackery"> [ $ "turtleduck.qky" loadfile ] now!
[ stack ] is switch.arg ( --> [ )
[ switch.arg put ] is switch ( x --> )
[ switch.arg release ] is otherwise ( --> )
[ switch.arg share
!= iff ]else[ done
otherwise ]'[ do ]done[ ] is case ( x --> )
[ $ "" swap witheach
[ nested quackery join ] ] is expand ( $ --> $ )
[ $ "F" ] is F ( $ --> $ )
[ $ "L" ] is L ( $ --> $ )
[ $ "R" ] is R ( $ --> $ )
[ $ "LBFRAFARFBL" ] is A ( $ --> $ )
[ $ "RAFLBFBLFAR" ] is B ( $ --> $ )
$ "A"
5 times expand
turtle
10 frames
witheach
[ switch
[ char F case [ 10 1 walk ]
char L case [ -1 4 turn ]
char R case [ 1 4 turn ]
otherwise ( ignore ) ] ]
1 frames</syntaxhighlight>
 
{{output}}
 
[[File:Quackery Hilbert curve.png]]
 
=={{header|Racket}}==
 
{{trans|Perl}}
 
<syntaxhighlight lang="racket">#lang racket
(require racket/draw)
(define rules '([A . (- B F + A F A + F B -)]
[B . (+ A F - B F B - F A +)]))
(define (get-cmds n cmd)
(cond
[(= 0 n) (list cmd)]
[else (append-map (curry get-cmds (sub1 n))
(dict-ref rules cmd (list cmd)))]))
(define (make-curve DIM N R OFFSET COLOR BACKGROUND-COLOR)
(define target (make-bitmap DIM DIM))
(define dc (new bitmap-dc% [bitmap target]))
(send dc set-background BACKGROUND-COLOR)
(send dc set-pen COLOR 1 'solid)
(send dc clear)
(for/fold ([x 0] [y 0] [θ (/ pi 2)])
([cmd (in-list (get-cmds N 'A))])
(define (draw/values x* y* θ*)
(send/apply dc draw-line (map (curry + OFFSET) (list x y x* y*)))
(values x* y* θ*))
(match cmd
['F (draw/values (+ x (* R (cos θ))) (+ y (* R (sin θ))) θ)]
['+ (values x y (+ θ (/ pi 2)))]
['- (values x y (- θ (/ pi 2)))]
[_ (values x y θ)]))
target)
(make-curve 500 6 7 30 (make-color 255 255 0) (make-color 0 0 0))</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
 
<syntaxhighlight lang="raku" line>use SVG;
 
role Lindenmayer {
has %.rules;
method succ {
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
}
}
 
my $hilbert = 'A' but Lindenmayer( { A => '-BF+AFA+FB-', B => '+AF-BFB-FA+' } );
 
$hilbert++ xx 7;
my @points = (647, 13);
 
for $hilbert.comb {
state ($x, $y) = @points[0,1];
state $d = -5 - 0i;
when 'F' { @points.append: ($x += $d.re).round(1), ($y += $d.im).round(1) }
when /< + - >/ { $d *= "{$_}1i" }
default { }
}
 
say SVG.serialize(
svg => [
:660width, :660height, :style<stroke:blue>,
:rect[:width<100%>, :height<100%>, :fill<white>],
:polyline[ :points(@points.join: ','), :fill<white> ],
],
);</syntaxhighlight>
See: [https://github.com/thundergnat/rc/blob/master/img/hilbert-perl6.svg Hilbert curve]
 
There is a variation of a Hilbert curve known as a [[wp:Moore curve|Moore curve]] which is essentially 4 Hilbert curves joined together in a loop.
<syntaxhighlight lang="raku" line>use SVG;
 
role Lindenmayer {
has %.rules;
method succ {
self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
}
}
 
my $moore = 'AFA+F+AFA' but Lindenmayer( { A => '-BF+AFA+FB-', B => '+AF-BFB-FA+' } );
 
$moore++ xx 6;
my @points = (327, 647);
 
for $moore.comb {
state ($x, $y) = @points[0,1];
state $d = 0 - 5i;
when 'F' { @points.append: ($x += $d.re).round(1), ($y += $d.im).round(1) }
when /< + - >/ { $d *= "{$_}1i" }
default { }
}
 
say SVG.serialize(
svg => [
:660width, :660height, :style<stroke:darkviolet>,
:rect[:width<100%>, :height<100%>, :fill<white>],
:polyline[ :points(@points.join: ','), :fill<white> ],
],
);</syntaxhighlight>
See: [https://github.com/thundergnat/rc/blob/master/img/moore-perl6.svg Moore curve]
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Hilbert curve
 
Line 1,347 ⟶ 3,644:
x1 = x2
y1 = y2
</syntaxhighlight>
</lang>
Output image:
[https://www.dropbox.com/s/anwtxtrnqhubh4a/HilbertCurve.jpg?dl=0 Hilbert curve]
 
=={{header|Ruby}}==
{{libheader|RubyGems}}
{{libheader|JRubyArt}}
<br/>
Implemented as a Lindenmayer System, depends on JRuby or JRubyComplete
<syntaxhighlight lang="ruby">
# frozen_string_literal: true
 
load_library :grammar
attr_reader :hilbert
def settings
size 600, 600
end
 
def setup
sketch_title '2D Hilbert'
@hilbert = Hilbert.new
hilbert.create_grammar 5
no_loop
end
 
def draw
background 0
hilbert.render
end
 
Turtle = Struct.new(:x, :y, :theta)
 
# Hilbert Class has access to Sketch methods eg :line, :width, :height
class Hilbert
include Processing::Proxy
 
attr_reader :grammar, :axiom, :draw_length, :production, :turtle
DELTA = 90.radians
def initialize
@axiom = 'FL'
@grammar = Grammar.new(
axiom,
'L' => '+RF-LFL-FR+',
'R' => '-LF+RFR+FL-'
)
@draw_length = 200
stroke 0, 255, 0
stroke_weight 2
@turtle = Turtle.new(width / 9, height / 9, 0)
end
 
def render
production.scan(/./) do |element|
case element
when 'F' # NB NOT using affine transforms
draw_line(turtle)
when '+'
turtle.theta += DELTA
when '-'
turtle.theta -= DELTA
when 'L'
when 'R'
else puts 'Grammar not recognized'
end
end
end
 
def draw_line(turtle)
x_temp = turtle.x
y_temp = turtle.y
turtle.x += draw_length * Math.cos(turtle.theta)
turtle.y += draw_length * Math.sin(turtle.theta)
line(x_temp, y_temp, turtle.x, turtle.y)
end
 
##############################
# create grammar from axiom and
# rules (adjust scale)
##############################
 
def create_grammar(gen)
@draw_length *= 0.6**gen
@production = @grammar.generate gen
end
end
</syntaxhighlight>
 
The grammar library:-
 
<syntaxhighlight lang="ruby">
# common library class for lsystems in JRubyArt
class Grammar
attr_reader :axiom, :rules
def initialize(axiom, rules)
@axiom = axiom
@rules = rules
end
 
def apply_rules(prod)
prod.gsub(/./) { |token| rules.fetch(token, token) }
end
 
def generate(gen)
return axiom if gen.zero?
 
prod = axiom
gen.times do
prod = apply_rules(prod)
end
prod
end
end
</syntaxhighlight>
 
=={{header|Rust}}==
Output is a file in SVG format. Implemented using a Lindenmayer system as per the Wikipedia page.
<syntaxhighlight lang="rust">// [dependencies]
// svg = "0.8.0"
 
use svg::node::element::path::Data;
use svg::node::element::Path;
 
struct HilbertCurve {
current_x: f64,
current_y: f64,
current_angle: i32,
line_length: f64,
}
 
impl HilbertCurve {
fn new(x: f64, y: f64, length: f64, angle: i32) -> HilbertCurve {
HilbertCurve {
current_x: x,
current_y: y,
current_angle: angle,
line_length: length,
}
}
fn rewrite(order: usize) -> String {
let mut str = String::from("A");
for _ in 0..order {
let mut tmp = String::new();
for ch in str.chars() {
match ch {
'A' => tmp.push_str("-BF+AFA+FB-"),
'B' => tmp.push_str("+AF-BFB-FA+"),
_ => tmp.push(ch),
}
}
str = tmp;
}
str
}
fn execute(&mut self, order: usize) -> Path {
let mut data = Data::new().move_to((self.current_x, self.current_y));
for ch in HilbertCurve::rewrite(order).chars() {
match ch {
'F' => data = self.draw_line(data),
'+' => self.turn(90),
'-' => self.turn(-90),
_ => {}
}
}
Path::new()
.set("fill", "none")
.set("stroke", "black")
.set("stroke-width", "1")
.set("d", data)
}
fn draw_line(&mut self, data: Data) -> Data {
let theta = (self.current_angle as f64).to_radians();
self.current_x += self.line_length * theta.cos();
self.current_y -= self.line_length * theta.sin();
data.line_to((self.current_x, self.current_y))
}
fn turn(&mut self, angle: i32) {
self.current_angle = (self.current_angle + angle) % 360;
}
fn save(file: &str, size: usize, order: usize) -> std::io::Result<()> {
use svg::node::element::Rectangle;
let x = 10.0;
let y = 10.0;
let rect = Rectangle::new()
.set("width", "100%")
.set("height", "100%")
.set("fill", "white");
let mut hilbert = HilbertCurve::new(x, y, 10.0, 0);
let document = svg::Document::new()
.set("width", size)
.set("height", size)
.add(rect)
.add(hilbert.execute(order));
svg::save(file, &document)
}
}
 
fn main() {
HilbertCurve::save("hilbert_curve.svg", 650, 6).unwrap();
}</syntaxhighlight>
 
{{out}}
[[Media:Hilbert_curve_rust.svg]]
 
=={{header|Scala}}==
===[https://www.scala-js.org/ Scala.js]===
<langsyntaxhighlight Scalalang="scala">@js.annotation.JSExportTopLevel("ScalaFiddle")
object ScalaFiddle {
// $FiddleStart
Line 1,400 ⟶ 3,896:
}
// $FiddleEnd
}</langsyntaxhighlight>
{{Out}}Best seen running in your browser by [https://scalafiddle.io/sf/x7t2zdK/0 ScalaFiddle (ES aka JavaScript, non JVM)].
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "draw.s7i";
include "keybd.s7i";
 
const integer: delta is 8;
 
const proc: drawDown (inout integer: x, inout integer: y, in integer: n) is forward;
const proc: drawUp (inout integer: x, inout integer: y, in integer: n) is forward;
 
const proc: drawRight (inout integer: x, inout integer: y, in integer: n) is func
begin
if n > 0 then
drawDown(x, y, pred(n));
line(x, y, 0, delta, white);
y +:= delta;
drawRight(x, y, pred(n));
line(x, y, delta, 0, white);
x +:= delta;
drawRight(x, y, pred(n));
line(x, y, 0, -delta, white);
y -:= delta;
drawUp(x, y, pred(n));
end if;
end func;
 
const proc: drawLeft (inout integer: x, inout integer: y, in integer: n) is func
begin
if n > 0 then
drawUp(x, y, pred(n));
line(x, y, 0, -delta, white);
y -:= delta;
drawLeft(x, y, pred(n));
line(x, y, -delta, 0, white);
x -:= delta;
drawLeft(x, y, pred(n));
line(x, y, 0, delta, white);
y +:= delta;
drawDown(x, y, pred(n));
end if;
end func;
 
const proc: drawDown (inout integer: x, inout integer: y, in integer: n) is func
begin
if n > 0 then
drawRight(x, y, pred(n));
line(x, y, delta, 0, white);
x +:= delta;
drawDown(x, y, pred(n));
line(x, y, 0, delta, white);
y +:= delta;
drawDown(x, y, pred(n));
line(x, y, -delta, 0, white);
x -:= delta;
drawLeft(x, y, pred(n));
end if;
end func;
 
const proc: drawUp (inout integer: x, inout integer: y, in integer: n) is func
begin
if n > 0 then
drawLeft(x, y, pred(n));
line(x, y, -delta, 0, white);
x -:= delta;
drawUp(x, y, pred(n));
line(x, y, 0, -delta, white);
y -:= delta;
drawUp(x, y, pred(n));
line(x, y, delta, 0, white);
x +:= delta;
drawRight(x, y, pred(n));
end if;
end func;
 
const proc: main is func
local
var integer: x is 11;
var integer: y is 11;
begin
screen(526, 526);
KEYBOARD := GRAPH_KEYBOARD;
drawRight(x, y, 6);
readln(KEYBOARD);
end func;</syntaxhighlight>
 
=={{header|Sidef}}==
Generic implementation of the Lindenmayer system:
<lang ruby>require('Image::Magick')
<syntaxhighlight lang="ruby">require('Image::Magick')
 
class Turtle(
Line 1,430 ⟶ 4,012:
primitive => 'line',
points => join(' ',
intround(x * scale + xoff),
intround(y * scale + yoff),
intround(newx * scale + xoff),
intround(newy * scale + yoff),
),
stroke => color,
Line 1,474 ⟶ 4,056:
turn = 0,
) {
method execute(string, repetitions, filename, rules) {
 
has stack var theta = []angle.deg2rad
has table var turtle = HashTurtle()
x: width,
 
y: height,
has turtle = Turtle(
x: angle: widthturn,
y: scale: heightscale,
angle color: turncolor,
scale xoff: scale xoff,
color yoff: color yoff,
xoff: xoff,)
yoff: yoff,
)
 
var stack = []
method init {
var table = Hash(
 
angle '+' => { turtle.deg2rad!turn(theta) },
turn '-' => { turtle.deg2rad!turn(-theta) },
 
table = Hash(
'+' => { turtle.turn(angle) },
'-' => { turtle.turn(-angle) },
':' => { turtle.mirror },
'[' => { stack.push(turtle.state) },
']' => { turtle.setstate(stack.pop) },
)
}
 
method execute(string, repetitions, filename, rules) {
 
repetitions.times {
Line 1,512 ⟶ 4,086:
table{c}.run
}
elsif (c.contains(/^[[:upper:]]\z/)is_uppercase) {
turtle.forward(len)
}
Line 1,519 ⟶ 4,093:
turtle.save_as(filename)
}
}</syntaxhighlight>
}
 
Generating the Hilbert curve:
var rules = Hash(
<syntaxhighlight lang="ruby">var rules = Hash(
a => '-bF+aFa+Fb-',
b => '+aF-bFb-Fa+',
Line 1,538 ⟶ 4,113:
)
 
lsys.execute('a', 6, "hilbert_curve.png", rules)</langsyntaxhighlight>
Output image: [https://github.com/trizen/rc/blob/master/img/hilbert-curve-sidef.png Hilbert curve]
{{out}}
[https://github.com/trizen/rc/blob/master/img/hilbert-curve-sidef.png Hilbert curve]
 
=={{header|Vala}}==
{{libheader|Gtk+-3.0}}
 
<langsyntaxhighlight lang="vala">struct Point{
int x;
int y;
Line 1,675 ⟶ 4,249:
Gtk.main();
return 0;
}</langsyntaxhighlight>
 
=={{header|VBScript}}==
Again no graphics in VBScript, so I write SVG in a HTML file and I open it in the default browser.
A turtle graphics library makes the sub that draws 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
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
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 hilb (n,a)
if n=0 then exit sub
x.rt a
hilb n-1,-a: x.fw 1:x.lt a: Hilb n - 1,a
x.fw 1
hilb n-1,a : x.lt a: x.fw 1: Hilb n - 1,-a
x.rt a
end sub
 
dim x
set x=new turtle
x.iangle=90
x.orient=0
x.incr=5
x.x=100:x.y=700
'star5
hilb 7,1
set x=nothing
</syntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|D}}
<syntaxhighlight lang="vbnet">Imports System.Text
 
Module Module1
 
Sub Swap(Of T)(ByRef a As T, ByRef b As T)
Dim c = a
a = b
b = c
End Sub
 
Structure Point
Dim x As Integer
Dim y As Integer
 
'rotate/flip a quadrant appropriately
Sub Rot(n As Integer, rx As Boolean, ry As Boolean)
If Not ry Then
If rx Then
x = (n - 1) - x
y = (n - 1) - y
End If
Swap(x, y)
End If
End Sub
 
Public Overrides Function ToString() As String
Return String.Format("({0}, {1})", x, y)
End Function
End Structure
 
Function FromD(n As Integer, d As Integer) As Point
Dim p As Point
Dim rx As Boolean
Dim ry As Boolean
Dim t = d
Dim s = 1
While s < n
rx = ((t And 2) <> 0)
ry = (((t Xor If(rx, 1, 0)) And 1) <> 0)
p.Rot(s, rx, ry)
p.x += If(rx, s, 0)
p.y += If(ry, s, 0)
t >>= 2
 
s <<= 1
End While
Return p
End Function
 
Function GetPointsForCurve(n As Integer) As List(Of Point)
Dim points As New List(Of Point)
Dim d = 0
While d < n * n
points.Add(FromD(n, d))
d += 1
End While
Return points
End Function
 
Function DrawCurve(points As List(Of Point), n As Integer) As List(Of String)
Dim canvas(n, n * 3 - 2) As Char
For i = 1 To canvas.GetLength(0)
For j = 1 To canvas.GetLength(1)
canvas(i - 1, j - 1) = " "
Next
Next
 
For i = 1 To points.Count - 1
Dim lastPoint = points(i - 1)
Dim curPoint = points(i)
Dim deltaX = curPoint.x - lastPoint.x
Dim deltaY = curPoint.y - lastPoint.y
If deltaX = 0 Then
'vertical line
Dim row = Math.Max(curPoint.y, lastPoint.y)
Dim col = curPoint.x * 3
canvas(row, col) = "|"
Else
'horizontal line
Dim row = curPoint.y
Dim col = Math.Min(curPoint.x, lastPoint.x) * 3 + 1
canvas(row, col) = "_"
canvas(row, col + 1) = "_"
End If
Next
 
Dim lines As New List(Of String)
For i = 1 To canvas.GetLength(0)
Dim sb As New StringBuilder
For j = 1 To canvas.GetLength(1)
sb.Append(canvas(i - 1, j - 1))
Next
lines.Add(sb.ToString())
Next
Return lines
End Function
 
Sub Main()
For order = 1 To 5
Dim n = 1 << order
Dim points = GetPointsForCurve(n)
Console.WriteLine("Hilbert curve, order={0}", order)
Dim lines = DrawCurve(points, n)
For Each line In lines
Console.WriteLine(line)
Next
Console.WriteLine()
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>Hilbert curve, order=1
 
|__|
 
 
Hilbert curve, order=2
__ __
__| |__
| __ |
|__| |__|
 
 
Hilbert curve, order=3
__ __ __ __
|__| __| |__ |__|
__ |__ __| __
| |__ __| |__ __| |
|__ __ __ __ __|
__| |__ __| |__
| __ | | __ |
|__| |__| |__| |__|
 
 
Hilbert curve, order=4
__ __ __ __ __ __ __ __ __ __
__| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__|
 
 
Hilbert curve, order=5
__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
|__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__| __| |__ |__|
__ |__ __| __ | __ | __ |__ __| __ | __ | __ |__ __| __
| |__ __| |__ __| | |__| |__| | |__ __| |__ __| | |__| |__| | |__ __| |__ __| |
|__ __ __ __ __| __ __ | __ __ __ __ | __ __ |__ __ __ __ __|
__| |__ __| |__ | |__| | |__| __| |__ |__| | |__| | __| |__ __| |__
| __ | | __ | |__ __| __ |__ __| __ |__ __| | __ | | __ |
|__| |__| |__| |__| __| |__ __| |__ __| |__ __| |__ __| |__ |__| |__| |__| |__|
__ __ __ __ |__ __ __ __ __ __ __ __ __ __| __ __ __ __
| |__| | | |__| | __| |__ |__| __| |__ |__| __| |__ | |__| | | |__| |
|__ __| |__ __| | __ | __ |__ __| __ | __ | |__ __| |__ __|
__| |__ __ __| |__ |__| |__| | |__ __| |__ __| | |__| |__| __| |__ __ __| |__
| __ __ __ __ | __ __ | __ __ __ __ | __ __ | __ __ __ __ |
|__| __| |__ |__| | |__| | |__| __| |__ |__| | |__| | |__| __| |__ |__|
__ |__ __| __ |__ __| __ |__ __| __ |__ __| __ |__ __| __
| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |
|__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __|
__| |__ |__| __| |__ |__| __| |__ __| |__ |__| __| |__ |__| __| |__
| __ | __ |__ __| __ | __ | | __ | __ |__ __| __ | __ |
|__| |__| | |__ __| |__ __| | |__| |__| |__| |__| | |__ __| |__ __| | |__| |__|
__ __ | __ __ __ __ | __ __ __ __ | __ __ __ __ | __ __
| |__| | |__| __| |__ |__| | |__| | | |__| | |__| __| |__ |__| | |__| |
|__ __| __ |__ __| __ |__ __| |__ __| __ |__ __| __ |__ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ __ __ __ __ __ __ __ __ | | __ __ __ __ __ __ __ __ __ |
|__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__| |__| __| |__ |__|
__ |__ __| __ __ |__ __| __ __ |__ __| __ __ |__ __| __
| |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| | | |__ __| |__ __| |
|__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __| |__ __ __ __ __|
__| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__ __| |__
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color, Point
import "dome" for Window
 
class Game {
static init() {
Window.title = "Hilbert curve"
Canvas.resize(650, 650)
Window.resize(650, 650)
__points = []
__width = 64
hilbert(0, 0, __width, 0, 0)
var col = Color.hex("#90EE90") // light green
var prev = __points[0]
for (p in __points.skip(1)) {
var curr = p
Canvas.line(prev.x, prev.y, curr.x, curr.y, col)
prev = curr
}
}
 
static hilbert(x, y, lg, i1, i2) {
if (lg == 1) {
var px = (__width - x) * 10
var py = (__width - y) * 10
__points.add(Point.new(px, py))
return
}
lg = lg >> 1
hilbert(x+i1*lg, y+i1*lg, lg, i1, 1-i2)
hilbert(x+i2*lg, y+(1-i2)*lg, lg, i1, i2)
hilbert(x+(1-i1)*lg, y+(1-i1)*lg, lg, i1, i2)
hilbert(x+(1-i2)*lg, y+i2*lg, lg, 1-i1, i2)
}
 
static update() {}
 
static draw(dt) {}
}</syntaxhighlight>
 
{{out}}
[[File:Wren-Hilbert_curve.png|400px]]
 
=={{header|XPL0}}==
Hilbert curve from turtle graphic program on Wikipedia.
<syntaxhighlight lang="xpl0">def Order=5, Size=15; \length of line segment
int Dir, X, Y;
 
proc GoFwd;
[case Dir&3 of
0: X:= X+Size;
1: Y:= Y+Size;
2: X:= X-Size;
3: Y:= Y-Size
other [];
Line(X, Y, \white\7);
];
 
proc Hilbert(Lev, Ang);
int Lev, Ang;
[if Lev then
[Dir:= Dir+Ang;
Hilbert(Lev-1, -Ang);
GoFwd;
Dir:= Dir-Ang;
Hilbert(Lev-1, Ang);
GoFwd;
Hilbert(Lev-1, Ang);
Dir:= Dir-Ang;
GoFwd;
Hilbert(Lev-1, -Ang);
Dir:= Dir+Ang;
];
];
 
[SetVid($12); \640x480 graphics
Dir:= 0; X:= 0; Y:= 0;
Move(X, Y);
Hilbert(Order, 1);
]</syntaxhighlight>
 
=={{header|Yabasic}}==
{{trans|Go}}
<syntaxhighlight lang="yabasic">width = 64
sub hilbert(x, y, lg, i1, i2)
if lg = 1 then
line to (width-x) * 10, (width-y) * 10
return
end if
lg = lg / 2
hilbert(x+i1*lg, y+i1*lg, lg, i1, 1-i2)
hilbert(x+i2*lg, y+(1-i2)*lg, lg, i1, i2)
hilbert(x+(1-i1)*lg, y+(1-i1)*lg, lg, i1, i2)
hilbert(x+(1-i2)*lg, y+i2*lg, lg, 1-i1, i2)
end sub
 
open window 655, 655
hilbert(0, 0, width, 0, 0)</syntaxhighlight>
 
=={{header|zkl}}==
Uses Image Magick and
the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<langsyntaxhighlight lang="zkl">hilbert(6) : turtle(_);
 
fcn hilbert(n){ // Lindenmayer system --> Data of As & Bs
Line 1,706 ⟶ 4,681:
}
img.writeJPGFile("hilbert.zkl.jpg");
}</langsyntaxhighlight>
Image at [http://www.zenkinetic.com/Images/RosettaCode/hilbert.zkl.jpg hilbert curve]
1,484

edits