我编写的代码描绘了Sierpinski分形。由于它使用递归,因此速度非常慢。你们中的任何人都知道如何在没有递归的情况下编写相同的代码,以便更快吗?这是我的代码:
midpoint[p1_, p2_] := Mean[{p1, p2}]
trianglesurface[A_, B_, C_] := Graphics[Polygon[{A, B, C}]]
sierpinski[A_, B_, C_, 0] := trianglesurface[A, B, C]
sierpinski[A_, B_, C_, n_Integer] :=
Show[
sierpinski[A, midpoint[A, B], midpoint[C, A], n - 1],
sierpinski[B, midpoint[A, B], midpoint[B, C], n - 1],
sierpinski[C, midpoint[C, A], midpoint[C, B], n - 1]
]
编辑:
我已经用混沌游戏方法编写了它,以防有人感兴趣。谢谢你的好答案! 这是代码:
random[A_, B_, C_] := Module[{a, result},
a = RandomInteger[2];
Which[a == 0, result = A,
a == 1, result = B,
a == 2, result = C]]
Chaos[A_List, B_List, C_List, S_List, n_Integer] :=
Module[{list},
list = NestList[Mean[{random[A, B, C], #}] &,
Mean[{random[A, B, C], S}], n];
ListPlot[list, Axes -> False, PlotStyle -> PointSize[0.001]]]
答案 0 :(得分:7)
这会将Scale
和Translate
与Nest
结合使用,以创建三角形列表。
Manipulate[
Graphics[{Nest[
Translate[Scale[#, 1/2, {0, 0}], pts/2] &, {Polygon[pts]}, depth]},
PlotRange -> {{0, 1}, {0, 1}}, PlotRangePadding -> .2],
{{pts, {{0, 0}, {1, 0}, {1/2, 1}}}, Locator},
{{depth, 4}, Range[7]}]
答案 1 :(得分:5)
如果您希望获得Sierpinski三角形的高质量近似值,可以使用称为chaos game的方法。这个想法如下 - 选择你想要定义的三个点作为Sierpinski三角形的顶点,并随机选择其中一个点。然后,只要您愿意,请重复以下步骤:
正如您所见at this animation,此过程最终会找出三角形的高分辨率版本。如果您愿意,可以多线程处理以使多个进程一次绘制像素,最终会更快地绘制三角形。
或者,如果您只想将递归代码转换为迭代代码,则可以选择使用工作列表方法。维护包含记录集合的堆栈(或队列),每个记录都包含三角形的顶点和数字n。最初将主要三角形的顶点和分形深度放入此工作列表中。然后:
这实质上是迭代地模拟递归。
希望这有帮助!
答案 2 :(得分:5)
您可以尝试
l = {{{{0, 1}, {1, 0}, {0, 0}}, 8}};
g = {};
While [l != {},
k = l[[1, 1]];
n = l[[1, 2]];
l = Rest[l];
If[n != 0,
AppendTo[g, k];
(AppendTo[l, {{#1, Mean[{#1, #2}], Mean[{#1, #3}]}, n - 1}] & @@ #) & /@
NestList[RotateLeft, k, 2]
]]
Show@Graphics[{EdgeForm[Thin], Pink,Polygon@g}]
然后用更高效的东西替换 AppendTo 。请参阅示例https://mathematica.stackexchange.com/questions/845/internalbag-inside-compile
修改
更快:
f[1] = {{{0, 1}, {1, 0}, {0, 0}}, 8};
i = 1;
g = {};
While[i != 0,
k = f[i][[1]];
n = f[i][[2]];
i--;
If[n != 0,
g = Join[g, k];
{f[i + 1], f[i + 2], f[i + 3]} =
({{#1, Mean[{#1, #2}], Mean[{#1, #3}]}, n - 1} & @@ #) & /@
NestList[RotateLeft, k, 2];
i = i + 3
]]
Show@Graphics[{EdgeForm[Thin], Pink, Polygon@g}]
答案 3 :(得分:3)
由于已经很好地涵盖了基于三角形的函数,因此这是一种基于栅格的方法 这迭代地构造pascal的三角形,然后取模2并绘制结果。
NestList[{0, ##} + {##, 0} & @@ # &, {1}, 511] ~Mod~ 2 // ArrayPlot
答案 4 :(得分:1)
Clear["`*"];
sierpinski[{a_, b_, c_}] :=
With[{ab = (a + b)/2, bc = (b + c)/2, ca = (a + c)/2},
{{a, ab, ca}, {ab, b, bc}, {ca, bc, c}}];
pts = {{0, 0}, {1, 0}, {1/2, Sqrt[3]/2}} // N;
n = 5;
d = Nest[Join @@ sierpinski /@ # &, {pts}, n]; // AbsoluteTiming
Graphics[{EdgeForm@Black, Polygon@d}]
(*sierpinski=Map[Mean, Tuples[#,2]~Partition~3 ,{2}]&;*)
以下是3D版本https://mathematica.stackexchange.com/questions/22256/how-can-i-compile-this-function
ListPlot@NestList[(# + RandomChoice[{{0, 0}, {2, 0}, {1, 2}}])/2 &,
N@{0, 0}, 10^4]
With[{data =
NestList[(# + RandomChoice@{{0, 0}, {1, 0}, {.5, .8}})/2 &,
N@{0, 0}, 10^4]},
Graphics[Point[data,
VertexColors -> ({1, #[[1]], #[[2]]} & /@ Rescale@data)]]
]
With[{v = {{0, 0, 0.6}, {-0.3, -0.5, -0.2}, {-0.3, 0.5, -0.2}, {0.6,
0, -0.2}}},
ListPointPlot3D[
NestList[(# + RandomChoice[v])/2 &, N@{0, 0, 0}, 10^4],
BoxRatios -> 1, ColorFunction -> "Pastel"]
]