How to generate random positions with distance bet

2019-06-14 07:56发布

Assume that I have a vector with 6 distance elements as

D = [10.5 44.8 30.01 37.2 23.4 49.1].

I'm trying to create random pair positions of a given distances, inside a 200 meters circle. Note that the distance D created by using (b - a).*rand(6,1) + a, with a = 10 and b = 50 in Matlab. I do not know how to generate the random pairs with given the distances.

Could anybody help me in generating this kind of scenario?

2条回答
再贱就再见
2楼-- · 2019-06-14 08:13

You can tackle the problem using a two-steps approach. You can

  1. randomly generate the first point and then you can consider the circle whose center is that point and whose radius is the distance in D
  2. once you did draw the circle, every point lying on that circle will have distance D from the first point previously created and by random selection of one of these candidates you'll have the second point

Let's see with an example: let's say you main circle has radius 200 and its center is (0,0) so we start by declaring some main variables.

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

Let's now consider the first distance, D(1)=10.5 and we now generate the first random point which (along with its paired point - I reckon you don't want one point inside and the other outside of the main circle) must lie inside the main circle

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

and at the end of this loop x and y will be our first point coordinates.

Now we shall generate all its neighbours, thus several candidates to be the second point in the pair. As said before, these candidates will be the points that lie on the circle whose center is (x,y) and whose radius is D(1)=10.5. We can create these candidates as follows:

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

Now xp and yp are two vectors that contain, respectively, the x-coordinates and y-coordinates of our candidates, thus we shall now randomly select one of these

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

Finally, the pair (x,y) is the first point and the pair (secondPoint_x, secondPoint_y) is our second point. The following plot helps summarizing these steps: enter image description here The red circle is the main area (center in (0,0) and radius 200), the red asterisk is the first point (x,y) the blue little circle has center (x,y) and radius 10.5 and finally the black asterisk is the second point of the pair (secondPoint_x, secondPoint_y), randomly extracted amongst the candidates lying on the blue little circle.

You must certainly can repeat the same process for all elements in D or rely on the following code, which does the very same thing without iterating through all the elements in 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;

Now x and y (and secondPoint_x and secondPoint_y by extension) will be vector of length 6 (because 6 are the distances) in which the i-th element is the i-th x (or y) component for the first (or second) point. enter image description here

查看更多
家丑人穷心不美
3楼-- · 2019-06-14 08:19

This is an improvement to Alessiox's answer. It follows same logic, first generate a set of points ([X1 Y1]) that have at least distance D from the main circle border, then generate the second set of points ([X2 Y2]) that have exact distance D from the first set.

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);

enter image description here

查看更多
登录 后发表回答