Hilbert curve: Difference between revisions
m
→{{header|Quackery}}: added link to description of method
m (→{{header|Quackery}}: added link to description of method) |
|||
(97 intermediate revisions by 38 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}}==
Line 14 ⟶ 312:
|}
<
INT level = 4; # <-- change this #
Line 70 ⟶ 368:
OD
END
</syntaxhighlight>
{{out}}
<pre> ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮
Line 104 ⟶ 402:
───╯ ╰───────╯ ╰───────╯ ╰───────╯ ╰───────╯ ╰──
</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}}
<
#define N 32
Line 177 ⟶ 582:
}
return 0;
}</
{{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}}
<
void main() {
Line 297 ⟶ 1,059:
return lines;
}</
{{out}}
<pre>Hilbert curve, order=1
Line 370 ⟶ 1,132:
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</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}}
<
Dim Shared As Integer ancho = 64
Line 392 ⟶ 1,461:
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 398 ⟶ 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.
<
import "github.com/fogleman/gg"
Line 432 ⟶ 1,684:
dc.Stroke()
dc.SavePNG("hilbert.png")
}</
=={{header|Haskell}}==
Line 442 ⟶ 1,694:
and folded to a list of points in a square of given size.
<
---------------------- 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
Line 462 ⟶ 1,747:
'd' -> [(-1, 1), (1, 1), (1, -1), (-1, -1)]
_ -> []
--------------------------- TEST -------------------------
main :: IO ()
Line 467 ⟶ 1,755:
let w = 1024
putStrLn $ svgFromPoints w $ hilbertPoints w (hilbertTree 6)
svgFromPoints :: Int -> [(Int, Int)] -> String
Line 492 ⟶ 1,760:
let sw = show w
points =
(unwords . fmap (((
in unlines
[ "<svg xmlns=\"http://www.w3.org/2000/svg\"",
unwords
"stroke-width=\"2\" stroke=\"red\" fill=\"transparent\"/>",
]</syntaxhighlight>
=={{header|IS-BASIC}}==
<
110 OPTION ANGLE DEGREES
120 GRAPHICS HIRES 2
Line 519 ⟶ 1,788:
250 CALL HILBERT(S,N-1,-P)
260 PLOT LEFT 90*P;
270 END DEF</
=={{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}}==
<
import java.util.ArrayList;
Line 654 ⟶ 1,970:
return;
}
}</
{{out}}
<pre>Hilbert curve, order=1
Line 733 ⟶ 2,049:
An implementation of GO. Prints an SVG string that can be read in a browser.
<
if (lg === 1) {
const px = (width - x) * spacing;
Line 786 ⟶ 2,102:
};
drawHilbert(6);</
===Functional===
Line 797 ⟶ 2,113:
Like the version above, generates an SVG string for display in a browser.
<
// ------------------ HILBERT CURVE ------------------
// Dict Char [Char] -> Int -> Int -> SVG string
const hilbertCurve = dictVector =>
dictRule => width =>
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;
};
// hilbertPoints :: Size
// hilbertPoints :: Int -> Tree Char
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 818 ⟶ 2,198:
[1, 1]
],
[1, -1],
[-1, -1],
Line 824 ⟶ 2,204:
[1, 1]
],
[1, -1],
[1, 1],
Line 830 ⟶ 2,210:
[-1, -1]
],
[-1, 1],
[1, 1],
Line 836 ⟶ 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);
// ---------------- GENERIC FUNCTIONS ----------------
const Node = v =>
// value of some
// more child
type:
nest: xs ||
});
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
//
const
// The binary function
// its arguments reversed.
? (a, b) => op(b, a)
: (a => b => op(b)(a));
// iterate :: (a -> a) -> a -> Gen [a]
// of f, starting with the seed value x.
function*
let v =
while (true) {
yield v;
v = f(v);
}
};
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables
// the shorter argument when one is non-finite,
// like cycle, repeat etc
"GeneratorFunction" !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take =
// The first n elements of a list,
// string of
.constructor.constructor.name ? (
}, ()
const x = xs.next();
return x.done ? [] : [x.value];
}).flat();
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith =
length: n
}, (_, i) => f(as[i], bs[i]));
};
// MAIN ---
return main();
})();</
=={{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.
<
Base.isless(p1::Vec2, p2::Vec2) = (p1.x == p2.x ? p1.y < p2.y : p1.x < p2.x)
Line 1,058 ⟶ 2,447:
signal_connect(endit, win, :destroy)
wait(cond)
</syntaxhighlight>
=={{header|Kotlin}}==
Line 1,064 ⟶ 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).
<
data class Point(var x: Int, var y: Int)
Line 1,129 ⟶ 2,518:
println()
}
}</
{{output}}
Line 1,226 ⟶ 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 1,244 ⟶ 2,680:
* <num> repeat the following draw command <num> times
* <any> move on canvas without drawing
<
local bit=bit32 or bit -- Lua 5.2/5.3 compatibilty
-- Hilbert curve implemented by Lindenmayer system
Line 1,331 ⟶ 2,767:
local str=arg[2] or "A"
draw(str:hilbert(n))
</syntaxhighlight>
{{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 1,354 ⟶ 2,790:
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
'''Works with:''' Mathematica 11
<syntaxhighlight lang
=={{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}}==
<
use List::Util qw(max min);
Line 1,398 ⟶ 2,947:
open $fh, '>', 'hilbert_curve.svg';
print $fh $svg->xmlify(-namespace=>'svg');
close $fh;</
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/hilbert_curve.svg Hilbert curve] (offsite image)
=={{header|
{{trans|Go}}
{{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}}==
<syntaxhighlight lang="java">int iterations = 7;
float strokeLen = 600;
int angleDeg = 90;
String axiom = "L";
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() {
background(0);
translate(xo, yo);
plot(radians(angleDeg));
}
void generate(int n) {
for (int i=0; i < n; i++) {
strokeLen *= 0.5;
String nextSentence = "";
for (int j=0; j < sentence.length(); j++) {
String ruleResult = rules.get(str(c), str(c));
nextSentence += ruleResult;
sentence = nextSentence;
}
}
void plot(float angle) {
for (int i=0; i < sentence.length(); i++) {
char c = sentence.charAt(i);
if (c == 'F') {
stroke(255);
line(0, 0, 0, -strokeLen);
translate(0, -strokeLen);
} else if (c == '+') {
rotate(angle);
} else if (c == '-') {
rotate(-angle);
}
}
}
void keyPressed() {
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}}===
<syntaxhighlight lang="python">iterations = 7
stroke_len = 600
angle_deg = 90
axiom = 'L'
sentence = axiom
rules = {
'L': '+RF-LFL-FR+',
'R': '-LF+RFR+FL-',
}
def setup():
global xo, yo
xo, yo =
strokeWeight(1)
generate(iterations)
def draw():
background(0)
translate(xo, yo)
plot(radians(angle_deg))
def generate(n):
global stroke_len, sentence
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):
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():
global angle_deg, xo, yo, stroke_len
if key == '-':
if
if key == 'z':
stroke_len /= 2
if keyCode == LEFT:
xo -= 50
if keyCode == RIGHT:
xo += 50
if keyCode == UP:
yo -= 50
if keyCode == DOWN:
yo += 50</syntaxhighlight>
=={{header|Python}}==
Line 1,542 ⟶ 3,188:
{{Works with|Python|3.7}}
<
from itertools import (chain, islice
Line 1,609 ⟶ 3,254:
def go(xy, tree):
r = d // 2
def
return (
xy[0] + (r * v[0]),
xy[1] + (r * v[1])
)
centres =
return chain.from_iterable(
) if tree['nest'] else centres
return
d = w // 2
Line 1,629 ⟶ 3,274:
'''Width of square canvas -> Point list -> SVG string'''
def go(
xs = ' '.join(map(points, xys))
return '\n'.join(
['<svg xmlns="http://www.w3.org/2000/svg"',
Line 1,642 ⟶ 3,286:
]
)
return
#
def main():
'''Testing generation of the SVG for a Hilbert curve'''
Line 1,653 ⟶ 3,297:
#
# Node :: a -> [Tree a] -> Tree a
Line 1,666 ⟶ 3,310:
def flip(f):
'''The (curried or uncurried) function f with its
arguments reversed.
'''
Line 1,683 ⟶ 3,325:
yield v
v = f(v)
return
# TEST ---------------------------------------------------
if __name__ == '__main__':
main()</
===Recursive===
<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}}==
<
# Project : Hilbert curve
Line 1,758 ⟶ 3,644:
x1 = x2
y1 = y2
</syntaxhighlight>
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]===
<
object ScalaFiddle {
// $FiddleStart
Line 1,811 ⟶ 3,896:
}
// $FiddleEnd
}</
{{Out}}Best seen running in your browser by [https://scalafiddle.io/sf/x7t2zdK/0 ScalaFiddle (ES aka JavaScript, non JVM)].
=={{header|Seed7}}==
<
include "draw.s7i";
include "keybd.s7i";
Line 1,897 ⟶ 3,982:
drawRight(x, y, 6);
readln(KEYBOARD);
end func;</
=={{header|Sidef}}==
Generic implementation of the Lindenmayer system:
<syntaxhighlight lang="ruby">require('Image::Magick')
class Turtle(
Line 1,926 ⟶ 4,012:
primitive => 'line',
points => join(' ',
),
stroke => color,
Line 1,970 ⟶ 4,056:
turn = 0,
) {
method execute(string, repetitions, filename, rules) {
x: width,
y: height,
var
'
'-' => { turtle.turn(-theta) },
':' => { turtle.mirror },
'[' => { stack.push(turtle.state) },
']' => { turtle.setstate(stack.pop) },
)
repetitions.times {
Line 2,008 ⟶ 4,086:
table{c}.run
}
elsif (c.
turtle.forward(len)
}
Line 2,015 ⟶ 4,093:
turtle.save_as(filename)
}
}</syntaxhighlight>
Generating the Hilbert curve:
<syntaxhighlight lang="ruby">var rules = Hash(
a => '-bF+aFa+Fb-',
b => '+aF-bFb-Fa+',
Line 2,034 ⟶ 4,113:
)
lsys.execute('a', 6, "hilbert_curve.png", rules)</
Output image: [https://github.com/trizen/rc/blob/master/img/hilbert-curve-sidef.png Hilbert curve]
=={{header|Vala}}==
{{libheader|Gtk+-3.0}}
<
int x;
int y;
Line 2,171 ⟶ 4,249:
Gtk.main();
return 0;
}</
=={{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}}
<
Module Module1
Line 2,285 ⟶ 4,471:
End Sub
End Module</
{{out}}
<pre>Hilbert curve, order=1
Line 2,362 ⟶ 4,548:
| __ | | __ | | __ | | __ | | __ | | __ | | __ | | __ |
|__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__| |__|</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}}
<
sub hilbert(x, y, lg, i1, i2)
Line 2,381 ⟶ 4,650:
open window 655, 655
hilbert(0, 0, width, 0, 0)</
=={{header|zkl}}==
Uses Image Magick and
the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<
fcn hilbert(n){ // Lindenmayer system --> Data of As & Bs
Line 2,412 ⟶ 4,681:
}
img.writeJPGFile("hilbert.zkl.jpg");
}</
Image at [http://www.zenkinetic.com/Images/RosettaCode/hilbert.zkl.jpg hilbert curve]
|