...所以要让我成为一棵树是一个挑战。
生成一个名为tree的程序或函数,该程序或函数采用一个整数参数N,并绘制一个N层深的勾股树,其中0层只是树干。
树的每个结点都应将三角形的顶点放置在周长上的任意点上(此点应均匀分布在至少5个等距的点上,或均匀分布在整个半圆上)。
根据您的时间,您的树也可以是3d,彩色或点亮。但是,这是代码高尔夫球,因此最小的文件为准。
编辑:一周之后,我将关闭比赛并接受最小的答案
...所以要让我成为一棵树是一个挑战。
生成一个名为tree的程序或函数,该程序或函数采用一个整数参数N,并绘制一个N层深的勾股树,其中0层只是树干。
树的每个结点都应将三角形的顶点放置在周长上的任意点上(此点应均匀分布在至少5个等距的点上,或均匀分布在整个半圆上)。
根据您的时间,您的树也可以是3d,彩色或点亮。但是,这是代码高尔夫球,因此最小的文件为准。
编辑:一周之后,我将关闭比赛并接受最小的答案
Answers:
g[n_,s_:1]:={p=RandomReal[q=Pi/2],r=##~Rotate~(o={0,0})&,t=Translate}~With~If[n<0,{},Join[#~t~{0,s}&/@(#~r~p&)/@g[n-1,s*Cos@p],t[#,s{Cos@p^2,1+Sin[2p]/2}]&/@(r[#,p-q]&)/@g[n-1,s*Sin@p],{Rectangle[o,o+s]}]]
f=Graphics@g@#&
当然,这不是最优雅/最短的方法。
用法: f[8]
这里有例如用于输出f[6]
和f[10]
分别。
有点不符合要求:
g[n_, s_:1] := With[{p},
r = Rotate;
t = Translate;
p = RandomReal[q = Pi/2];
If[n < 0, {},
Join[
(t[#, {0, s}] &) /@ (r[#, p, {0, 0}] &) /@ g[n - 1, s*Cos[p]],
(t[#, s {Cos[p]^2, 1 + Sin[2 p]/2}] &) /@ (r[#, p - q, {0, 0}] &) /@
g[n - 1, s*Sin[p]],
{Rectangle[{0, 0}, {s, s}]}
]
]
]
f = Graphics@g[#] &
Show
在那里,Module
也是不必要的。
Show
提示,但是我该如何摆脱Module
呢?如果我不声明p
本地,它将在递归调用中被覆盖,所以我不能用相同的两个调用p
,对吗?
Block
,它比短Module
。
这不是完全有效,因为您不能限制递归深度。但是问题只是在此方面需要解决方案。:)
startshape t
c(q)=cos(q/2)^2
d(q)=1+sin(q)/2
p=acos(-1)
shape t{w=rand(p)
SQUARE[x .5 .5]t[trans 0 1 c(w) d(w)]t[trans c(w) d(w) 1 1]}
结果看起来像这样
对于另外46个字符(总共180个字符),您甚至可以使用以下颜色:
startshape t
c(q)=cos(q/2)^2
d(q)=1+sin(q)/2
p=acos(-1)
shape t{w=rand(p)
SQUARE[x .5 .5 h 25 sat 1 b .2]t[trans 0 1 c(w) d(w) b .08 .8 h 2.2]t[trans c(w) d(w) 1 1 b .08 .8 h 2.2]}
编辑:似乎realtime
不能用作适当的随机生成器种子。因此,我们将为此使用环境变量并像这样运行程序:
gs -c 20 $RANDOM -f tree.ps
要么
gswin32c -c 20 %RANDOM% -f tree.ps
现在,我们的树木难以预测。14个字节被添加到总数中。其他更改:1)现在在命令行上传递了程序参数。2)没有明确的迭代计数器-堆栈大小用于此目的(左分支旋转角度存储在堆栈上,以便稍后绘制右分支)。3)没有所需深度的命名变量-堆栈大小是其在堆栈上的偏移量。它留在出口处,即不消耗。
srand
250 99 translate
50 50 scale
/f{
count
dup index div dup 1 le{
0 exch 0 setrgbcolor
0 0 1 1 rectfill
0 1 translate
rand 5 mod 1 add 15 mul
gsave
dup rotate
dup cos dup scale
f
grestore
dup cos dup dup mul
exch 2 index sin mul translate
dup 90 sub rotate
sin dup scale 1
f
pop
}{pop}ifelse
}def
f
我认为这很明显-图形状态已准备好,并且f
对于每个连续的深度级别,都为“左”和“右”分支递归调用了两次过程。使用矩形1x1
大小(请参见原始比例)可以避免乘以边长的麻烦。左分支的旋转角度是随机的-使用了5个随机等距的除法之一-我认为它可以防止出现统一情况下的丑陋情况。
所需深度超过20左右可能会很慢。
接下来是高尔夫版本,使用ASCII编码的二进制令牌(请参阅链接主题中的luser droog的答案)。注意,cos
,sin
,rand
不能使用此记号。
/${{<920>dup 1 4 3 roll put cvx exec}forall}def srand 250 99<AD>$ 50 50<8B>$/f{count(8X68)$ 1 le{0(>)$ 0<9D>$ 0 0 1 1<80>$ 0 1<AD>$ rand 5 mod 1 add 15<~CecsG2u~>$ cos<388B>$ f(M8)$ cos(88l>)$ 2(X)$ sin<6CAD38>$ 90<A988>$ sin<388B>$ 1 f pop}{pop}(U)$}def f
。
/${{<920>dup 1 4 3 roll put cvx exec}forall}def
srand
250 99<AD>$
50 50<8B>$
/f{
count(8X68)$
1 le{
0(>)$ 0<9D>$
0 0 1 1<80>$
0 1<AD>$
rand 5 mod 1 add 15
<~CecsG2u~>$
cos<388B>$
f
(M8)$
cos(88l>)$
2(X)$ sin<6CAD38>$
90<A988>$ sin<388B>$
1
f
pop
}{pop}(U)$
}def
f
-dGraphicsAlphaBits
是抗锯齿输出的标志,以防止较大正方形的锯齿状边缘,可以省略(或在例如环境变量中“隐藏”)。有些人可能会更喜欢没有此标志(树的叶子具有更多的“体积”)。好吧,那20个字节并不重要。我会说使用ASCII编码的二进制令牌可以减少20%到25%(根据链接的主题答案判断)。也许不使用ASCII编码即可享受50%的折扣,每个系统名称令牌2个二进制字节。看起来像一些通常会胜出的语言;)
我写咖啡脚本很脏,但是找不到适合python3的绘图包:-/
Q=(n)->X=(D=document).body.appendChild(C=D.createElement('Canvas')).getContext('2d');C.width=C.height=400;M=Math;T=[[175,400,50,i=0]];S=M.sin;C=M.cos;while [x,y,l,a]=T[i++]
X.save();X.translate x,y;X.rotate -a;X.fillRect 0,-l,l,l;X.restore();T.push [e=x-l*S(a),f=y-l*C(a),g=l*C(b=M.random()*M.PI/2),d=a+b],[e+g*C(d),f-g*S(d),l*S(b),d-M.PI/2] if i<2**n
在javascript中稍微漂亮一点,我对for循环更满意,但是如果没有[x,y,z] = A语法,我简直不能说短到足以击败coffeescript
function Q(n){X=(D=document).body.appendChild(C=D.createElement('Canvas')).getContext('2d');C.width=C.height=600;M=Math;T=[[275,400,50,i=0]];while(A=T[i++]){X.save();X.translate(x=A[0],y=A[1]);X.rotate(-(a=A[3]));X.fillRect(0,-(l=A[2]),l,l);X.restore();S=M.sin;C=M.cos;i<M.pow(2,n)&&T.push([e=x-l*S(a),f=y-l*C(a),g=l*C(b=M.random()*M.PI/2),d=a+b],[e+g*C(d),f-g*S(d),l*S(b),d-M.PI/2])}}
不得不说我有点高兴,这几乎是mathematica解决方案时间的两倍:-/实际使用它:http : //jsfiddle.net/FK2NX/3/
X
return 方法X
,都可以将它们链接起来。您还可以通过保存M.sin
和M.cos
使用单字符变量来保存另一组好的字符。
s=M.sin
。
rotate
使用this
,sin
但不使用。您需要做类似的事情R=X.rotate.bind(X)
,但这可能不再值得了。