对于实验,我们在Matlab中生成了一些由8个磁盘制成的图像。我们限制了磁盘之间以及磁盘和框架之间的最小距离以及磁盘重心(COG)的位置。在上部升降机“第三”中用COG组成一个组合的例子
FraXYs = {{4.32, 3.23}, {35.68, 26.75}}
stiDisks = {{{8, 11}, 1}, {{10, 17}, 1}, {{16, 24}, 1}, {{25, 22},1},
{{31, 22}, 1}, {{7, 21}, 2}, {{16, 12}, 2}, {{19, 22}, 2}}
Graphics[{White, EdgeForm[Thick],
Rectangle @@ FraXYs,
Red, Disk[{14.77, 18.91}, 1],
Blue, Opacity[.6], EdgeForm[Black],
Blue, Thickness[0.003],
Opacity[1],
Black,
Disk[#[[1]], #[[2]]] & /@ stiDisks}, ImageSize -> {400, 300}]
我想在Mathematica中产生这些刺激。以下是我正在处理的元素(特征和约束)。措施以厘米为单位。形状的重心(COG)定义为磁盘位置的区域。
功能:
刺激框架: {{xMin,xMin},{xMax,yMax}}
FraXYs = {{4.32, 3.23}, {35.68, 26.75}}
5个小磁盘:,半径为
rSmall=1
3张大盘:,半径为
rLarge=2
约束:
形状边缘之间的最小距离:
minDistSha=1
形状边缘和边框之间的最小距离:
minDistFra=1
形状COG距离中心的距离:
minDistCogCenter=2
我可能需要将磁盘的COG限制在距离中心一定角度(极坐标系中的θ坐标?)。所以我可以选择磁盘坐标来限制它们的COG位于极坐标每22.5度
angleBin=22.5
Mathematica中是否有有用的功能可以在除Selct
之外的约束条件下实现选择。
我很想知道是否可以生成具有特定COG位置的1种成分的封闭式。
指示性地,我需要获得1000个组合的池。使用36度的“θ约束”,我应该提取10 * 100组合,其COG位于10个不同的θ条上,距离中心最小或固定距离。
请告诉我是否需要澄清。谢谢你的关注。
答案 0 :(得分:5)
这可能会让你开始。这是一种简单的拒绝方法,可以随机生成圆圈,丢弃不符合要求的合奏。
参数是小圆和大圆的框大小,数字和半径,以及最小间隔。最后一个用于距边界的距离和圆之间的距离。我将它的重心加倍到帧约束的中心。显然,这种用法可以通过添加更多参数来推广。
为了评估这是否有可能找到可行的合奏,我打印循环的次数。此外,我使用了一个非常必要的Catch / Throw机制(一些我无法删除的实验工具)。
---编辑---
以下代码与我最初发布的内容略有不同。它将重心圆分开为红色。
要处理它位于某个指定角度的约束,可以生成如下所示,旋转以放入正确的角度位置,并重新检查从圆到帧边界的距离。可能有一些更聪明的东西,不太可能给予拒绝,同时仍然保持一致性。实际上我完全不确定我编码的内容是否允许配置空间的均匀分布。如果是这样,旋转的影响很可能会破坏该属性。
---结束编辑---
randomConfiguration[{xlo_, ylo_}, {xhi_, yhi_}, nsmall_, nlarge_,
rsmall_, rlarge_, minsep_] := Catch[Module[
{found = False, xsmall, ysmall, xlarge, ylarge, smallsep, largesep,
smallcircs, largecircs, cog, cen, indx = 0},
smallsep = {rsmall + minsep, -rsmall - minsep};
largesep = {rlarge + minsep, -rlarge - minsep};
cen = {xhi - xlo, yhi - ylo};
While[! found,
found = True;
indx++;
xsmall = RandomReal[{xlo, xhi} + smallsep, nsmall];
ysmall = RandomReal[{ylo, yhi} + smallsep, nsmall];
xlarge = RandomReal[{xlo, xhi} + largesep, nlarge];
ylarge = RandomReal[{ylo, yhi} + largesep, nlarge];
smallcircs = Transpose[{xsmall, ysmall}];
Do[If[
Norm[smallcircs[[i]] - smallcircs[[j]]] <= 2*rsmall + minsep,
found = False; Break[]], {i, nsmall - 1}, {j, i + 1, nsmall}];
largecircs = Transpose[{xlarge, ylarge}];
Do[If[
Norm[largecircs[[i]] - largecircs[[j]]] <= 2*rlarge + minsep,
found = False; Break[]], {i, nlarge - 1}, {j, i + 1, nlarge}];
Do[If[
Norm[smallcircs[[i]] - largecircs[[j]]] <=
rsmall + rlarge + minsep, found = False; Break[]], {i,
nsmall}, {j, nlarge}];
cog = (rsmall^2*Total[smallcircs] +
rlarge^2*Total[largecircs])/(nsmall*rsmall^2 +
nlarge*rlarge^2);
If[Norm[cog - cen] <= 2*minsep, found = False;];
];
Print[indx];
Throw[{{cog, rsmall},Map[{#, rsmall} &, smallcircs],
Map[{#, rlarge} &, largecircs]}]
]]
示例:
{smallc, largec} =
randomConfiguration[{4.32, 3.23}, {35.68, 26.75}, 5, 3, 1, 2, 1];
13
FraXYs = {{4.32, 3.23}, {35.68, 26.75}};
{cog, smallc, largec} =
randomConfiguration[{4.32, 3.23}, {35.68, 26.75}, 5, 3, 1, 2, 1];
Graphics[{White, EdgeForm[Thick], Rectangle @@ FraXYs, Red,
Apply[Disk, cog], Blue, Opacity[.6], EdgeForm[Black], Blue,
Thickness[0.003], Opacity[1], Black,
Disk[#[[1]], #[[2]]] & /@ Join[smallc, largec]},
ImageSize -> {400, 300}]