How to generate uniformly distributed random coordinates inside a cuboid such that the distance between points is greater than a constant value?
16 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I want to generate uniform randomly distributed points inside a cube. The points should also satisfy a condition that they should be atleast a constant distance apart. I have written a matlab code, but the end result is not uniformly distributed points. I think the issue is that i am creating one random point at a time. Please have a look at the attached script. Any suggestions?
clear
close all
% matlab code to generate random coordinates for inclusions
% translation of inclusions into polymer box
% here uniform distribution is considered
% polymer box size 80*80*100
% inclusions should not overlap each other
% inclusions should not cross the boundary too
% in order to avoid inclusions from crossing the boundary, consider a
% shrinked box dimension
% all units in Angstroms
% size of inclusion 8*8*10
% RVE dimension
xlo = 0;
xhi = 80;
ylo = 0;
yhi = 80;
zlo = 0;
zhi = 100;
% inclusion dimension
xlo_incl = 0;
xhi_incl = 8;
ylo_incl = 0;
yhi_incl = 8;
zlo_incl = 0;
zhi_incl = 10;
% half the diagonal distance of inclusion should be avoided from RVE size
% to prevent inclusions from overlapping the boundary
% tolerance of 1 Angstroms is provided
point1 = [xlo_incl ylo_incl zlo_incl];
point2 = [xhi_incl yhi_incl zhi_incl];
dia_dist = norm(point2-point1);
trim_tolerance = 1;
trim_dist = dia_dist*0.5+trim_tolerance;
% actual dimension to work with
xlo_trim = xlo+trim_dist;
xhi_trim = xhi-trim_dist;
ylo_trim = ylo+trim_dist;
yhi_trim = yhi-trim_dist;
zlo_trim = zlo+trim_dist;
zhi_trim = zhi-trim_dist;
% generate random numbers
num_incl = 8;
dia_tolerance = 3; % tolerance value for seperation of RVE(angstroms)
dia_tot = dia_dist+dia_tolerance;
x_rand = xlo_trim+(xhi_trim-xlo_trim)*rand(1,1);
y_rand = ylo_trim+(yhi_trim-ylo_trim)*rand(1,1);
z_rand = zlo_trim+(zhi_trim-zlo_trim)*rand(1,1);
rand_coord = zeros(num_incl,3);
rand_coord(1,:) = [x_rand y_rand z_rand];
i = 1;
while(i<8)
check_matrix =(dia_tot+1);
x_rand1 = xlo_trim+(xhi_trim-xlo_trim)*rand(1,1);
y_rand1 = ylo_trim+(yhi_trim-ylo_trim)*rand(1,1);
z_rand1 = zlo_trim+(zhi_trim-zlo_trim)*rand(1,1);
coord_new = [x_rand1 y_rand1 z_rand1];
for j=1:i
coord_new;
rand_coord(j,:);
check_dist(j) = norm(coord_new-rand_coord(j,:));
end
check_dist;
A = all(check_matrix(:) > dia_tot);
if A > 0
rand_coord(i+1,:) = coord_new;
i = i+1;
end
end
4 comentarios
Walter Roberson
el 8 de Dic. de 2021
Check out the previous posts on the topic of sphere packing, and you will find that I (among other people) have posted with uniform distribution in space algorithms -- at least uniform distribution in the places that it attempts the place the points, with there being no certainty that the resulting packing will be uniformly distributed !
In particular if you look at the one that was modified not long ago for placement into a cylinder, you will see a specific demonstration there that the algorithm that I used for placing inside the cylinder results in uniform spatial distribution of attempt points (placing uniformly inside a circular cross-section requires a mathematical trick.)
John D'Errico
el 16 de Dic. de 2021
Editada: John D'Errico
el 16 de Dic. de 2021
If the points are truly uniformly distributed, then there is no theortetical minimum distance between pairs of points. Does the fact that you are generating them one at a time matter? No. The fallacy lies in your expectations, that a uniform distribution has no points that lie closely together.
As Walter has pointed out, this becomes a sphere packing problem, but sphere packing is not so trivial.
Simple schemes like rejection sampling can work, but don't expect to get any kind of dense sampling that might be even close to optimal, certainly not in a reasonable amount of time. You can also try things like starting with a random sample, then perturbing points to move away from each other when they are too close or too far from their nearest neighbors. You could think of that in terms of a force on each point, that depends upon the distance to their nearest neighbor.
Of course that result will no longer be truly uniformly distributed. However, it may be the best thing you can do in a reasonable time if you want some sort of fairly dense packing subject to a minimum distance.
Respuestas (1)
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!