更新:如何使用Matlab对立方体中非均匀尺寸的随机非重叠球体进行建模?

时间:2014-08-04 21:01:12

标签: matlab random geometry

我正在尝试使用MATLAB为立方体中的非均匀尺寸球体(非重叠)生成随机位置。以下代码中的for循环似乎永远不会结束。我不知道代码中缺少什么。我没有运行代码。球体(n)= 10; dims = [10 10 10]

    function [ c r ] = randomSphere( dims )
    % creating one sphere at random inside [0..dims(1)]x[0..dims(2)]x...
    % radius and center coordinates are sampled from a uniform distribution 
    % over the relevant domain.
    % output: c - center of sphere (vector cx, cy,... )
    %         r - radius of sphere (scalar)
    r = rand(1); % you might want to scale this w.r.t dims or other consideration
    c = r + rand( size(dims) )./( dims - 2*r ); % make sure sphere does not exceed boundaries

   function ovlp = nonOverlapping( centers, rads )
   % check if several spheres with centers and rads overlap or not
   ovlp = false;
   if numel( rads ) == 1
   return; % nothing to check for a single sphere
   end
   dst = sqrt( sum( bsxfun( @minus, permute( centers, [1 3 2] ),...
                             permute( centers, [3 1 2] ) ).^2, 3) );
   ovlp = dst >= bsxfun( @plus, rads, rads.' ); %' all distances must be smaller than r1+r2
   ovlp = any( ovlp(:) ); % all must not overlap


   function [centers rads] = sampleSpheres( dims, n )
   % dims is assumed to be a row vector of size 1-by-ndim

   % preallocate
   ndim = numel(dims);
   centers = zeros( n, ndim );
   rads = zeros( n, 1 );
   ii = 1;
   while ii <= n
   [centers(ii,:), rads(ii) ] = randomSphere( dims );     
   if nonOverlapping( centers(1:ii,:), rads(1:ii) )
     ii = ii + 1; % accept and move on
   end
end

2 个答案:

答案 0 :(得分:1)

如果不编写一行代码,我会提出以下想法: 在精细网格中(使用网格网格)将3d空间分散。现在,您将不再使用rand()作为坐标,而是随机为您的球体选择一个有效的预定义坐标元组。因此,首先选择当前球体的半径,然后从所有可能的坐标中过滤出有效的坐标,即带有半径的球体不会与边界或另一个球体相交。

Best,Nras。

答案 1 :(得分:0)

您可以迭代添加新的随机球体,检查它们是否有效(不与其他球体相交,不超过边界等),并接受有效的随机球体,直到您有足够的随机球体。

function [ c r ] = randomSphere( dims )
% creating one sphere at random inside [0..dims(1)]x[0..dims(2)]x...
% radius and center coordinates are sampled from a uniform distribution 
% over the relevant domain.
%
% output: c - center of sphere (vector cx, cy,... )
%         r - radius of sphere (scalar)
r = rand(1); % you might want to scale this w.r.t dims or other consideration
c = r + rand( size(dims) )./( dims - 2*r ); % make sure sphere does not exceed boundaries

既然我们知道如何生成单个随机球体,我们想知道如何检查几个球体是否重叠

function ovlp = nonOverlapping( centers, rads )
% check if several spheres with centers and rads overlap or not
ovlp = false;
if numel( rads ) == 1
   return; % nothing to check for a single sphere
end
dst = sqrt( sum( bsxfun( @minus, permute( centers, [1 3 2] ),...
                                 permute( centers, [3 1 2] ) ).^2, 3 );
ovlp = dst >= bsxfun( @plus, rads, rads.' ); %' all distances must be smaller than r1+r2
ovlp = any( ovlp(:) ); % all must not overlap

最后,我们可以按顺序开始生成几个球体,检查每个球体之后的重叠:

function [centers rads] = sampleSpheres( dims, n )
% dims is assumed to be a row vector of size 1-by-ndim

% preallocate
ndim = numel(dims);
centers = zeros( n, ndim );
rads = zeros( n, 1 );
ii = 1;
while ii <= n
    [centers(ii,:), rads(ii) ] = randomSphere( dims );     
    if nonOverlapping( centers(1:ii,:), rads(1:ii) )
         ii = ii + 1; % accept and move on
    end
end

请注意,这种方法可能会让您陷入无限循环,以防您要求n较小的dims - {填充'所有空间的n球体少于n然后你无法生成新的。请谨慎选择dimsr,您可能还希望更好地控制采样{{1}}的分布。