【问题标题】:How to generate random positions with distance between them?如何生成它们之间有距离的随机位置?
【发布时间】:2016-07-16 21:07:19
【问题描述】:

假设我有一个包含 6 个距离元素的向量

D = [10.5 44.8 30.01 37.2 23.4 49.1].

我正在尝试在 200 米的圆圈内创建给定距离的随机对位置。请注意,在 Matlab 中使用(b - a).*rand(6,1) + aa = 10b = 50 创建的距离 D。我不知道如何生成给定距离的随机对。

有人可以帮我生成这种场景吗?

【问题讨论】:

  • 既然你知道D = (b - a).*rand(6,1) + a的关系,你想得到ab吗?

标签: matlab math geometry


【解决方案1】:

这是对Alessiox's answer 的改进。它遵循相同的逻辑,首先生成一组点([X1 Y1]),它们与主圆边界的距离至少为D,然后生成第二组点([X2 Y2]),它们与主圆边界的距离精确到D第一组。

cx = 50; cy = -50; cr = 200;
D = [10.5 44.8 30.01 37.2 23.4 49.1]';
n = numel(D);

R1 = rand(n, 1) .* (cr - D);
T1 = rand(n, 1) * 2 * pi;
X1 = cx+R1.*cos(T1);
Y1 = cy+R1.*sin(T1);

T2 = rand(n, 1) * 2 * pi;
X2 = X1+D.*cos(T2);
Y2 = Y1+D.*sin(T2);

【讨论】:

  • 非常感谢@saastn 的帮助,能否贴出画圆的代码?
  • @user3727281 当然,我使用来自here方法12
  • 非常感谢@saastn
  • 在另一种情况下,您如何看待第二个点在圆外的位置?因为我想要圆圈内的所有点?你怎么能解决它?谢谢
  • @ saastn 我的代码有错误,我修复了它。非常感谢。
【解决方案2】:

您可以使用两步方法解决问题。你可以

  1. 随机生成第一个点,然后可以考虑以该点为圆心,半径为D中的距离的圆
  2. 绘制圆后,该圆上的每个点与之前创建的第一个点的距离为D,通过随机选择其中一个候选点,您将获得第二个点

让我们看一个例子:假设你的 main 圆的半径为200,它的中心是(0,0),所以我们首先声明一些主要变量。

MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;

现在让我们考虑第一个距离,D(1)=10.5,我们现在生成第一个随机点(连同它的配对点 - 我认为你不希望一个点在主圈内,另一个点在主圈外)必须位于在主圈内

r=D(1); % let's concentrate on the first distance
while true
    x=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
    y=((MAINRADIUS-2*r) - (-MAINRADIUS+2*r))*rand(1,1) + (-MAINRADIUS+2*r);
    if x^2+y^2<=(MAINRADIUS-2*r)^2
        break;
    end
end

在循环结束时,xy 将是我们的第一个点坐标。

现在我们将生成它的所有邻居,因此有几个候选者将成为该对中的第二个点。如前所述,这些候选点将位于圆心为(x,y)、半径为D(1)=10.5 的圆上。我们可以按如下方式创建这些候选项:

% declare angular spacing
ang=0:0.01:2*pi; 
% build neighbour points
xp=r*cos(ang)+x;
yp=r*sin(ang)+y;

现在xpyp 是两个向量,分别包含候选对象的 x 坐标和 y 坐标,因此我们现在将随机选择其中一个

% second point
idx=randsample(1:length(xp),1);
secondPoint_x=xp(idx);
secondPoint_y=yp(idx);

最后,(x,y) 是第一个点,(secondPoint_x, secondPoint_y) 是我们的第二个点。下图有助于总结这些步骤: 红色圆圈是主要区域(中心在 (0,0) 和半径 200),红色星号是第一个点 (x,y) 蓝色小圆圈的中心 (x,y) 和半径 10.5 最后黑色星号是(secondPoint_x, secondPoint_y) 对的第二个点,在位于蓝色小圆圈上的候选者中随机抽取。

您当然可以对D 中的所有元素重复相同的过程,或者依赖以下代码,它会执行相同的操作,而无需遍历D 中的所有元素。

MAINCENTER_x=0;
MAINCENTER_y=0;
MAINRADIUS=200;

D = [10.5 44.8 30.01 37.2 23.4 49.1];

% generate random point coordinates
while true
    x=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
    y=((MAINRADIUS-2*D) - (-MAINRADIUS+2*D)).*rand(1,6) + (-MAINRADIUS+2*D);
    if all(x.^2+y.^2<=(MAINRADIUS-2*D).^2)
        break;
    end
end

% declare angular spacing
ang=0:0.01:2*pi; 
% build neighbour points
xp=bsxfun(@plus, (D'*cos(ang)),x');
yp=bsxfun(@plus, (D'*sin(ang)),y');

% second points
idx=randsample(1:size(xp,2),length(D));
secondPoint_x=diag(xp(1:length(D),idx));
secondPoint_y=diag(yp(1:length(D),idx));
%plot
figure(1);
plot(MAINRADIUS*cos(ang)+MAINCENTER_x,MAINRADIUS*sin(ang)+MAINCENTER_y,'r'); %main circle
hold on; plot(xp',yp');                          % neighbours circles
hold on; plot(x,y,'r*');                         % first points (red asterisks)
hold on; plot(secondPoint_x,secondPoint_y,'k*'); %second points (black asterisks)
axis equal;

现在xy(以及secondPoint_xsecondPoint_y 的扩展)将是长度为6 的向量(因为6 是距离),其中第i 个元素是第i 个x(或 y)分量用于第一个(或第二个)点。

【讨论】:

  • 为什么不在极坐标中生成随机点?然后你可以删除while循环并生成大量候选邻居。
  • 非常感谢@Alessiox。阿莱西奥克斯!你能给我代码如何在你的图中用不同颜色绘制圆圈吗?
  • @Alessiox 嗨,你能解释一下 randsample 和 diag 函数生成第二个点是什么意思吗?非常感谢
  • @user3727281 您也可以阅读 Matlab 文档,但简而言之,randsample(A,B) 从人口 A 中随机选择 B 点,而 diag 从矩阵的对角线中选择元素.更详细地说,使用randsample,我们在邻居数量中选择 6 个 ID,因为我们有 6 个距离,因此每个距离一个。 diag 帮助我们在与整数 1-6 映射后返回 6 个值
  • @user3727281 在diag命令之前我们有6个索引(idx),我们的目标是从xp的第一行中取出第一个索引对应的列,对应的列从xp 的第二行到第二个索引,依此类推(yp 也是如此)。作为diag 的替代方案,您可以使用sub2ind(),如下secondPoint_x=xp(sub2ind(size(xp), 1:size(xp,1), idx));yp 也是如此)。
猜你喜欢
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 2021-01-26
  • 2015-09-03
相关资源
最近更新 更多