Это может помочь вам начать.Это простой метод отклонения, позволяющий генерировать круги случайным образом, отбрасывая ансамбли, которые не соответствуют требованиям.
Аргументами являются размер блока, числа и радиусы малых и больших кругов, а также минимальное расстояние.Этот последний используется как для расстояний до границы, так и для расстояний между кругами.Я удваиваю его для центра тяжести до ограничения рамки.Ясно, что это использование можно обобщить, добавив больше аргументов.
Для оценки вероятности поиска жизнеспособных ансамблей я печатаю количество раз в цикле.Также я использую механизм Catch / Throw, который на самом деле не нужен (артефакт некоторого эксперимента, который я не удосужился удалить).
--- edit ---
Код ниже имеетскромные изменения по сравнению с тем, что я изначально разместил.Он отделяет круг центра тяжести от красного.
Чтобы справиться с ограничением, лежащим под определенным углом, можно создать, как показано ниже, повернуть, чтобы установить правильное угловое положение, и перепроверить расстояния от окружностей.к границе кадра.Возможно, есть что-то умнее, что с меньшей вероятностью приведет к отклонению, при этом сохраняя единообразие.На самом деле я совсем не уверен, что то, что я кодировал, дает равномерное распределение из пространства допустимых конфигураций.Если это так, то влияние поворота, скорее всего, уничтожит это свойство.
--- end edit ---
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}]