generating a matrix of coordinates without certain values

Hello,
I am building a code to generate a large number of points (80000) inside a sphere where the columns are the x,y,z coordinates, and they are randomly generated like so, using this function in a loop:
function [x,y,z] = generate_coordinate(R)
rng('shuffle');
phi = 2*pi*rand(1,1);
costheta = -1 + 2*rand(1,1);
u = rand(1,1);
theta = acos(costheta);
r = R * nthroot(u,3);
x = r * sin(theta) * cos(phi);
y = r * sin(theta) * sin(phi);
z = r * cos(theta);
end
Problem is I need the point to be at a minimum distance of dist_r_min (I check that by clustering in KDTree and using rangesearch if the points are in range).
So basically I want to know how is it possible to ask MATLAB to generate a point where this condition is applied? to pick a random point in this space yet not choosing a point that doesn't satisfy the condition?
For now I tried to solve this by generating the point again in a loop if it doesn't satisfy the condition, it takes too much time.
Edit: By points being at a minmum distance of dist_r_min, I meant from each other, point 1 and point 2 can't have their centers in a distance smaller than dist_r_min, not from the center of the sphere. Sorry for any confusion

 Réponse acceptée

David Hill
David Hill le 27 Juil 2022
Modifié(e) : David Hill le 27 Juil 2022
D=5;%max diameter
d=2;%min diameter
rng('shuffle');
c=(rand(3,1e7)-.5)*D;
n=vecnorm(c);
c(:,n<d/2|n>D/2)=[];%matrix of randomly generated corrdinates meeting requirements

4 commentaires

D=5;%max diameter
rng('shuffle');
m=.1;%min distance between points
y=D;
while vecnorm(y)>D/2
y=(rand(1,3)-.5)*D;
end
while size(y,1)<1000
Y=(rand(1,3)-.5)*D;
if vecnorm(Y)>D/2
continue;
end
if all(pdist2(y,Y)>m)
y=[y;Y];
end
end
Thank you very much for your help!
This is a solution that is similair to what I tried, and it works well with cases where you have a small number of points, but after 40k points the rand function doesn't work well with finding more empty space where a point can sit. (want to get to 80k points in a sphere of 1000 units radius and the minimal distance between each point is 12 units)
So instead I was looking for something like randperm, where I know when I generate the next point it will be random but it will not get into a prohibited zone of any of the other points.
Is that possible?
I ran you perimeters above and it took about 1-2 minutes to execute (only 24 seconds below). Once you have the matrix of random points you can just keep it in memory and use randperm to select however many points you want.
D=2000;%max diameter
rng('shuffle');
m=12;
y=D;
tic;
while vecnorm(y)>D/2
y=(rand(1,3)-.5)*D;
end
while size(y,1)<80000
Y=(rand(1,3)-.5)*D;
if vecnorm(Y)>D/2
continue;
end
if all(pdist2(y,Y)>m)
y=[y;Y];
end
end
toc;
Elapsed time is 23.882563 seconds.
y(randperm(80000,10),:)
ans = 10×3
-210.4035 -61.3991 -460.5519 442.9074 -240.0659 -797.7330 166.2713 -190.8297 552.1111 -434.0397 -249.6562 208.0519 883.2772 -76.3169 180.8346 975.3998 -61.3202 136.7793 -89.1616 -291.7357 208.2421 -675.3150 -132.0166 577.1093 -412.0220 -800.4817 -131.9315 500.8794 197.8124 165.6223
Nicola Seraphim
Nicola Seraphim le 28 Juil 2022
Modifié(e) : Nicola Seraphim le 28 Juil 2022
Ok now that I tried it works really well!! Thank you.
it does, however, become slow if you increase the minimal distance to be 40 units around 40k points generated. Still, it is a big improvment that what I initially did.
Edit: after 42k points it really takes more than an hour to generate another 2k points and the time form there only increasing (trying to get 70-80k points). I think this is because the rand function can no longer find space to fit the points, that's why I was searching for something similair to randperm if possible.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by