绘制希尔伯特曲线


12

希尔伯特曲线是一种空间填充曲线,它基本上将一条线映射到一个平面。线中的每个点仅对应于平面中的一个点,而平面中的每个点仅对应于线上的一个点。显示的是希尔伯特曲线的迭代0到4:

迭代0到4:

该任务的目标:如上所述,编写绘制希尔伯特曲线第四次迭代的代码。您的代码应该完整-换句话说,如果您创建绘制希尔伯特曲线的函数,则您的代码必须调用该函数。输出可以直接显示在屏幕上,也可以将输出写入图像文件。曲线可以旋转或翻转,但直线必须相交成直角,并且输出不能拉伸。可以理解ASCII技术,但不会被接受。以字节为单位的最短代码胜出!


输入次数是多少?还是我们可以选择至少4个值?
路易斯·门多

ASCII艺术被认为是图形的吗?
加布里埃尔·贝纳米

没有; 抱歉-那将是另一个问题的重复
J. Antonio Perez

@JorgePerez曲线可以有不同的方向吗?像你的例子垂直翻转或90度旋转版本
路易斯Mendo

是! 尽管整体形状仍必须是正方形
J. Antonio Perez

Answers:


7

R,90个字节

n=scan();a=1+1i;b=1-1i;z=0;for(k in 1:n)z=c((w<-1i*Conj(z))-a,z-b,z+a,b-w)/2;plot(z,t="s")

@Luis Mendo发布的链接中使用的算法的无耻R端口。

因为n=5我们得到:

在此处输入图片说明


7

MATL39 38字节

O5:"tZjJ*JQ-wJq+t2+&y2j+_v2/]XG25Y01ZG

这将迭代次数作为输入。如果您想对其进行硬编码,请替换i为数字。

该方案是由乔纳斯Lundgren的所示的Matlab代码的端口这里

结果如下所示。您也可以在MATL Online上尝试花费几秒钟来产生输出。该编译器是实验性的;您可能需要刷新页面,然后在最初不起作用时再次按“运行”。

在此处输入图片说明

说明

O          % Push 0. This is the initial value of "z" in the original code
5:"        % Do 5 times
  t        %   Duplicate
  Zj       %   Complex conjugate
  J*       %   Multiply by 1j (imaginary unit). This is "w" in the original code
  JQ-      %   Subtract 1+1j
  w        %   Swap: brings copy of "z" to top
  Jq+      %   Add 1-1j
  t        %   Duplicate
  2+       %   Add 2
  &y       %   Duplicate the third element from top
  2j+_     %   Add 2j and negate
  v        %   Concatenate the three matrices vertically
  2/       %   Divide by 2
]          % End
XG         % Plot (in complex plane). The numbers are joined by straight lines
25Y0       % Push string 'square'
1ZG        % Make axis square

您能否解释一下代码的工作原理?
J. Antonio Perez

该算法与链接中的完全相同。但我要添加一个解释
Luis Mendo

@Jorge说明添加
路易斯Mendo

天哪,您的基地比我的
基地

@flawr全部归功于Jonas Lundgren :-)
Luis

6

MATLAB,264个 262 161字节

除基本计算希尔伯特曲线的“导数”,然后再通过“求和”“积分”外,该函数的工作原理几乎相同。这将代码大小减少了很多字节。

function c;plot(cumsum([0,h(1,1+i,4)]));axis equal;end function v=h(f,d,l);v=d*[i*f,1,-i*f];if l;l=l-1;D=i*d*f;w=h(f,d,l);x=h(-f,D,l);v=[x,D,w,d,w,-D,-x];end;end

旧版

这只是一种简单的递归方法。为了简单起见,我使用复数来存储矢量信息。您可以在零件上更改曲线h(0,1,1+i,4)。第一个参数p=0是初始位置,第二个参数f是方向(+1-1)的标记,第三个参数d是应绘制曲线的方向/旋转,第四个参数l是递归深度。

function c;hold on;h(0,1,1+i,4);axis equal;end function p=h(p,f,d,l);q=@plot;if l;l=l-1;d=i*d*f;p=h(p,-f,d,l);q(p+[0,d]);p=p+d;d=-i*d*f;p=h(p,f,d,l);q(p+[0,d]);p=p+d;p=h(p,f,d,l);d=-i*d*f;q(p+[0,d]);p=p+d;p=h(p,-f,d,l);else;q(p + d*[0,i*f,1+i*f,1]);p=p+d;end;end

这是旧版本中的样子:

这是2015b的样子:

->

1
在Matlab R2015b中,它 <3的颜色绘制
Luis

哈哈太酷了:)
更加糟糕的

@LuisMendo现在我有了一个cumsum绝妙的主意!
瑕疵的

3

MATLAB / Octave,202字节

我注意到版本@LuisMendo链接 就是比以前更短的方式“手工制作”的解决方案,但使用完全不同的方法。我现在以CW的形式发布高尔夫版本:

该版本基于Lindenmayer系统方法:

A=zeros(0,2);B=A;C=A;D=A;n=[0,1];e=[1,0];for k=1:4;a=[B;n;A;e;A;-n;C];b=[A;e;B;n;B;-e;D];c=[D;-e;C;-n;C;e;A];D=[C;-n;D;-e;D;n;B];A=a;B=b;C=c;end;A=[0,0;cumsum(A)];plot(A(:,1),A(:,2));axis off;axis equal

在此处输入图片说明


3

JavaScript(ES6),266 ... 233232字节

希尔伯特曲线的SVG渲染。

document.write('<svg><path fill=none stroke=red d="M8 8'+(f=(i,s='2',d=x=y=8)=>i?f(i-1,s.replace(/./g,c=>[32410401423,,10432423401][+c]||c)):s.replace(/./g,c=>c-4?(d+=c&1&&c-2,''):`L${x+=4-'4840'[d&=3]} ${y+=4-'0484'[d]}`))(5)+'">')

感谢Neil,节省了1个字节


1
试试fill=none
Neil

2

Python 3中,177个 175 171字节

希尔伯特曲线的Lindenmayer系统的简单实现。欢迎打高尔夫球!

编辑: -2字节感谢Kade。-3个字节,用于重组希尔伯特曲线的生成方式。-1个字节,感谢ETHproductions。

from turtle import*;s="a";exec('t=""\nfor c in s:t+=c>"F"and"+-abFF-+baFFba-+FFab+-"[c<"b"::2]or c\ns=t;'*5)
for c in s:
 if"-">c:rt(90)
 elif"F">c:lt(90)
 elif"a">c:fd(9)

在此处输入图片说明

开球

import turtle

hilbert_seq = "a"

for _ in range(5):
    new_seq = ""
    for char in hilbert_seq:
        if char == "a":
            new_seq += "-bF+aFa+Fb-"
        elif char == "b":
            new_seq += "+aF-bFb-Fa+"
        else:
            new_seq += char
    hilbert_seq = new_seq

for char in hilbert_seq:
    if char == "F":
        turtle.forward(9)
    elif char == "+":
        turtle.right(90)
    elif char == "-":
        turtle.left(90)

更改表单的格式t可以节省两个字节:t+=[[c,"+AF-BFB-FA+"][c=="B"],"-BF+AFA+FB-"][c=="A"]。由于该图案是他们两个我不知道差不多了,如果有一些方法来使用..
卡德

也许改变if c>"E":,以if"E"<c:挽救一个字节?
ETHproductions 2016年

1

MSWLogo(6.5b版),136个字节

基于此处的最终希尔伯特曲线程序。

to h :n :a :l
if :n=0[stop]
rt :a
h :n-1(-:a):l
fd :l
lt :a
h :n-1 :a :l
fd :l
h :n-1 :a :l
lt :a
fd :l
h :n-1(-:a):l
rt :a
end
h 5 90 9

h定义了一个函数,该函数需要迭代次数:n(从1开始),angle :a和length :l。它是递归的,:a在两个实例中取反的角度调用其自身的较低迭代,以获取正确的方向。

  • rt :alt :a向右旋转乌龟(追踪其路径的三角形东西),以:a度为单位。
  • fd :l:l逐步移动乌龟。

最后,该函数称为:h 5 90 9。可以将乌龟隐藏额外的2个字节,ht

第(5-1)次迭代


左上角发生了什么事?
瑕疵的

@flawr那是乌龟。可以通过追加将其隐藏ht
莫妮卡

1

Mathematica 128字节

Graphics[Line@AnglePath[Total/@Split[Cases[Nest[#/.{-2->(s=##&@@#&)[l={-1,2,0,1,-2,0,-2,1,0,2,-1}],2->s@-l}&,{-2},4],-1|1|0],#!=0&][[;;-2,;;-2]]*Pi/2]]

如果愿意,可以用不同的迭代次数替换上面的4。

做为具有整数序列而非字符串序列的Lindenmayer系统,因此第二条生产规则只是第一条规则的负数。这个版本是151个位元组。

Jonas Lundgren的MATLAB代码的端口只有128个字节。

z=0;Graphics[Line[{Re[#],Im[#]}&/@Flatten[Table[w=I*Conjugate[z];z={w-(a=1+I),z-(b=1-I),z+a,b-w}/2,{k,5}][[5]]]],AspectRatio->1]

我看到在Mathematica的未来版本中,这可能会变得很短,例如:

Graphics@HilbertCurve[n]

http://mathworld.wolfram.com/HilbertCurve.html


1

LindenMASM,63字节

LindenMASM答案的另一个问题是?太棒了!

STT
AXI A
INC 5
SET F 0
RPL A -BF+AFA+FB-
RPL B +AF-BFB-FA+
END

再一次,由于Python的一些绘制错误turtle,有时在您运行此脚本时,整个图形并不存在。但是,您可以看到它确实有效:

第4次迭代

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.