非重叠球体条件

时间:2014-08-21 16:21:38

标签: matlab conditional-statements

我想检查一个条件,以便两个球体不重叠。这意味着两个球体之间的距离应大于(r1 + r2)。我已经发布了下面的完整代码,第二个函数似乎有问题,检查非重叠条件。我可以在没有这个条件的情况下运行代码但是当我包含它不执行时。变量的值是dims = [10 10 10]和n = 25;让我知道你的想法,有没有其他更好的方法来制定这个条件?

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
disp (centers);
disp (rads);

2 个答案:

答案 0 :(得分:0)

基本上你是根据球体之间的距离加起来的新球体。中心及其半径。因此,您需要将所有范围与最新添加进行比较,即centers(end,:)rads(end)

这就是这个功能的作用 -

function not_ovlp = nonOverlapping( centers, rads )

if numel( rads ) == 1
    not_ovlp = true;
    return; % nothing to check for a single sphere
end

center_dist = sqrt(sum(bsxfun(@minus,centers(1:end-1,:),centers(end,:)).^2,2));
radsum = rads(end) + rads(1:end-1);
not_ovlp = all(center_dist > radsum);

return;

true时,它会将输出设为not an overlap


示例说明

假设你开始在这个非重叠的愿望清单中添加球体。因此,您选择第一个具有中心(1,2,1)和半径2的球体。然后,对于下一个,您以(3,4,2)为中心,半径为0.5

因此,你有 -

centers =[
    1 2 1;
    3 4 2]

rads = [2;0.5]

现在,您需要检查此最新球体是否与先前选定的球体重叠,您可以使用前面列出的功能找到它 -

nonOverlapping( centers, rads )

它提供1表示此新添加的内容不重叠,可以包含在列表中。

答案 1 :(得分:0)

或者只是遍历所有可能的球体组合,直到全部通过或者一次失败。

ovlp = false;

% assume centers is mx3 matrix for m sphere centres
numSpheres = size(centers,1);

for k=1: numSpheres
    for m=k+1:numSpheres
        dist = sqrt((centers(k,1)-centers(m,1))^2 + (centers(k,2)-centers(m,2))^2 ...
                    + (centers(k,3)-centers(m,3))^2);
        if dist <= (rads(k)+rads(m))
            ovlp = true;
            break;
        end
     end
     if ovlp
         break;
     end
end

除非您需要知道哪个球体相交,哪个球体不相交。

编辑错误在上面的内部for循环中。应该从k + 1迭代到numSpheres而不是从2。