我想在Manipulate
结构中包含一些区域图,但渲染速度几乎非常慢。代码是
ClearAll[regions, rplot]
r:regions[n_Integer, o_Integer] := r = Apply[And,
Subsets[Table[(#1 - Cos[t])^2 + (#2 - Sin[t])^2 <= 1, {t, 2 Pi/n,
2 Pi, 2 Pi/n}], {o}], {1}] &
r:rplot[n_Integer, o_Integer] := r = Show[{RegionPlot[
Evaluate[regions[n, o][x, y]], {x, -2, 2}, {y, -2, 2},
PlotRange -> {{-2, 2}, {-2, 2}}, PlotRangePadding -> .1,
Frame -> False, PlotPoints -> 100],
Graphics[Table[Circle[{Cos[t], Sin[t]}, 1], {t, 2 Pi/n, 2 Pi, 2 Pi/n}]]}]
产生类似
的图形GraphicsGrid[{{rplot[3, 2], rplot[5, 3]}, {rplot[7, 2], rplot[4, 1]}}]
以上大约需要40秒才能在我的计算机上进行计算和渲染。 任何人都可以建议一种方法来更快地获得类似质量的图形吗?
注1:我已经记住了图形对象,因此每次在我的演示中都不需要重新计算它 - 但即使是第一次它也太慢了。
注2:我对栅格化图像感到满意,因此洪水填充类型解决方案可能是一种选择...
注3:我需要Manipulate[
rplot[n, o], {n, 2, 10, 1, Appearance -> "Labeled"}, {{o, 1},
Range[1, (n + 1)/2], ControlType -> RadioButtonBar}]
这样的东西才能使用。
答案 0 :(得分:4)
你可以做这样的事情
rplot[n_Integer, o_Integer] := Module[{centres, masks, opacity = .3,
colours, region, img, createmask},
centres = Table[Through[{Re, Im}[Exp[I t]]], {t, 2 Pi/n, 2 Pi, 2 Pi/n}];
createmask[centres_] := Fold[ImageMultiply, #[[1]], Rest[#]] &@
(ColorNegate[ Image[Graphics[Disk[#, 1], PlotRange -> {{-2, 2}, {-2, 2}},
PlotRangePadding -> .1], ColorSpace -> "Grayscale"]] & /@ centres);
masks = createmask /@ Subsets[centres, {o}];
colours = PadRight[#, Length[masks], #] & @ (List @@@ ColorData[1, "ColorList"]);
region[img_, col_] :=
SetAlphaChannel[ColorCombine[ImageMultiply[img, #] & /@ col, "RGB"],
ImageMultiply[img, opacity]];
img = Fold[ImageCompose, #[[1]], Rest[#]] &@(MapThread[region, {masks, colours}]);
Overlay[{img, Graphics[Circle[#, 1] & /@ centres, PlotRangePadding -> .1,
PlotRange -> {{-2, 2}, {-2, 2}}]}]
]
然后GraphicsGrid[{{rplot[3, 2], rplot[5, 3]}, {rplot[7, 2], rplot[4, 1]}}]
会产生类似
修改强>
将之前的修改移至单独的答案。
答案 1 :(得分:3)
先生。向导让我意识到虽然我有RegionPlot
中可以使用的区域的分析形式,但如果我获得了边界的参数化形式,那么我可以使用ParametricPlot
。那么,让我们这样做!
i th (i=0,...,n-1
)圆在复平面上被参数化
Exp[I t] + Exp[2 i Pi I / n]
中的t
[0, 2 Pi]
。{/ p>
我们可以求解找到i
th 和(i+o-1)
th 圈子的交集,其中o
是重叠次数,如问题的原始代码。这给出了
point[n_, o_, i_] := {Cos[(2 i Pi)/n] + Cos[(2 Pi (i + o - 1))/n],
Sin[(2 i Pi)/n] + Sin[(2 Pi (i + o - 1))/n]}
现在我们可以将从原点到point[n,o,i]
的弧参数化,并将它们反映在从原点到point[n,o,i]
的整个线上。使用参数s
对两者进行插值,得出参数化区域
area[n_, o_, i_, t_, s_] := With[{a = 2 Sin[((2 + n - 2 o) (1 - t) )/(2 n) Pi],
b = (2 - 4 i + 2 t + n t - 2 o (1 + t))/(2 n) Pi,
c = ((2 + n - 2 o) (1 - t) - 4 i)/(2 n) Pi},
{a (s Cos[b] + (1 - s) Sin[c]) , -a (s Sin[b] - (1 - s) Cos[c])}]
然后我们可以定义
rplot[n_Integer, o_Integer] := ParametricPlot[Evaluate[
Table[area[n, o, i, t, s], {i, 0, n - 1}]], {t, 0, 1}, {s, 0, 1},
Mesh -> False, MaxRecursion -> 1, Frame -> False, Axes -> False,
PlotRange -> 2.1 {{-1, 1}, {-1, 1}},
Epilog -> {Table[Circle[{Cos[t], Sin[t]}, 1], {t, 0, 2 Pi (n-1)/n, 2 Pi/n}],
Red, Point[Table[point[n, o, i], {i, 1, n}]]}]
GraphicsGrid[{{rplot[3, 2], rplot[5, 3]}, {rplot[7, 2], rplot[4, 1]}}]
生成
答案 2 :(得分:3)
我之前发布此内容作为我的其他答案的补充。它的灵感来自Simon的分析方法,并通过一些修改来加速提升
intersect[n_, o_] :=
With[{a = Pi/2 - (o-1) Pi/n},
If[o-1 >= n/2, Return[{}]]; (* intersection is {} *)
Polygon[
Join[Table[{Sin[a] + Sin[phi], (-Cos[a] + Cos[phi])}, {phi, -a, a-2 a/10, 2 a/10}],
Table[{Sin[a] + Sin[phi], (Cos[a] - Cos[phi])}, {phi, a, -a+2 a/10, -2 a/10}]]]]
rplot2[n_, o_] := With[{pl = intersect[n, o], opac = .3, col = ColorData[1]},
Graphics[{{Opacity[opac],
Table[{col[k], Rotate[pl, Mod[o - 1, 2] Pi/n + 2 Pi k/n, {0, 0}]}, {k, n}]},
{Black, Circle[Through[{Re, Im}[Exp[I #]]]] & /@ (Range[n] 2 Pi/n)}}]
]
首先,我使用n
和o
的给定值,i
- 和i+o-1
- 圈之间的交叉区域是与第一个和第o
个圆之间的交叉区域相同,除了在角度2 Pi (i-1)/n
上旋转之外,因此只需计算一次区域并使用Rotate
旋转该区域就足够了
此外,我没有使用ParametricPlot绘制交叉区域,而是使用Polygon
,所以我只需要计算边界上的一些点,这样可以节省时间。
GraphicsGrid[{{rplot2[3, 2], rplot2[5, 2]}, {rplot2[7, 3], rplot2[4, 1]}}]
的结果类似于
我得到的时间是
rplot2[10, 3]; // Timing
(* ==> {0.0016, Null} *)
与Simon的解决方案相比
rplot[10, 3]; // Timing
(* ==> {0.16519, Null} *)
答案 3 :(得分:1)
如果圆圈总是以如图所示的均匀环排列,则应该有一个圆圈交叉点的解析解。我将从环上布置的每个圆圈之间的度数开始。
我将在时间允许的情况下探索这种方法。
二进制光栅化一系列位于正确位置的磁盘
为每个栅格分配唯一的2次幂值而不是
添加数组
根据总数数组中每个点的值计算唯一的重叠集
将正确的颜色映射到结果数组并生成输出
光栅方法的第一次粗略传递,仅作为概念证明。您可以看到每个区域都有一个唯一的阴影,这只是该点栅格的总和。
raster =
1 - First@Binarize@Rasterize@Graphics[#, PlotRange -> {{-2, 2}, {-2, 2}}] &;
disks =
Table[raster @ Disk[{Cos[t], Sin[t]}, 1], {t, 2 Pi/#, 2 Pi, 2 Pi/#}] &;
n = 5;
array = disks[n] * 2^Range[0, n - 1] //Total;
ArrayPlot[array]
第二稿,添加颜色。它仍然相当笨重。
n = 7; o = 2;
sets = Table[
NestList[RotateLeft, PadLeft[Table[1, {o + i}], n], n - 1],
{i, 0, n - o}
];
colors = NestList[
Mean /@ Partition[#, 2, 1, 1] &,
List @@@ Take[ColorData[4, "ColorList"], n],
n - o
];
rules = Append[Rule @@@ Flatten[{sets, colors}, {{2, 3}}], _ -> {1, 1, 1}];
Replace[Transpose[disks[n], {3, 2, 1}], rules, {2}] // Image