2016-03-23 108 views
2

我需要隨機生成固定數量的非重疊圓圈。我可以顯示圓,在這種情況下20,位於隨機與此一段代碼,不重疊隨機分佈的圈子

for i =1:20 
    x=0 + (5+5)*rand(1) 
    y=0 + (5+5)*rand(1) 
    r=0.5 
    circle3(x,y,r) 
    hold on 
    end 

然而圓重疊,我希望避免這種情況。這是通過以前的用戶Mathematica https://mathematica.stackexchange.com/questions/69649/generate-nonoverlapping-random-circles實現的,但我使用MATLAB,我想堅持下去。

對於重複性,這是功能,CIRCLE3,我使用繪製圓

function h = circle3(x,y,r) 
d = r*2; 
px = x-r; 
py = y-r; 
h = rectangle('Position',[px py d d],'Curvature',[1,1]); 
daspect([1,1,1]) 

謝謝。

+0

請顯示您嘗試檢查重疊的內容。 – SpamBot

+0

不一樣,但讓我想起了這一點:http://stackoverflow.com/q/7833534/97160 – Amro

+0

我認爲你可以切割你的地區使用瓷磚成正方形,然後填寫在那裏的圓圈 – GameOfThrows

回答

1

您可以保存所有以前繪製的圓圈列表。在 之後,隨機選擇一個新的圓圈,確認它不與先前繪製的圓相交。

代碼例如:

nCircles = 20; 
circles = zeros(nCircles ,2); 
r = 0.5; 

for i=1:nCircles 
    %Flag which holds true whenever a new circle was found 
    newCircleFound = false; 

    %loop iteration which runs until finding a circle which doesnt intersect with previous ones 
    while ~newCircleFound 
     x = 0 + (5+5)*rand(1); 
     y = 0 + (5+5)*rand(1); 

     %calculates distances from previous drawn circles 
     prevCirclesY = circles(1:i-1,1); 
     prevCirclesX = circles(1:i-1,2); 
     distFromPrevCircles = ((prevCirclesX-x).^2+(prevCirclesY-y).^2).^0.5; 

     %if the distance is not to small - adds the new circle to the list 
     if i==1 || sum(distFromPrevCircles<=2*r)==0 
      newCircleFound = true; 
      circles(i,:) = [y x]; 
      circle3(x,y,r) 
     end 

    end 
    hold on 
end 

*通知,如果環的量太大相對於其中X和Y座標是從繪製的範圍內,所述循環可以無限運行。 爲了避免它 - 相應地定義這個範圍(它可以被定義爲nCircles的函數)。

output example

1

如果你滿意的暴力破解,可以考慮這種解決方案:

N = 60;      % number of circles 
r = 0.5;      % radius 
newpt = @() rand([1,2]) * 10; % function to generate a new candidate point 

xy = newpt(); % matrix to store XY coordinates 
fails = 0;  % to avoid looping forever 
while size(xy,1) < N 
    % generate new point and test distance 
    pt = newpt(); 
    if all(pdist2(xy, pt) > 2*r) 
     xy = [xy; pt]; % add it 
     fails = 0;  % reset failure counter 
    else 
     % increase failure counter, 
     fails = fails + 1; 
     % give up if exceeded some threshold 
     if fails > 1000 
      error('this is taking too long...'); 
     end 
    end 
end 

% plot 
plot(xy(:,1), xy(:,2), 'x'), hold on 
for i=1:size(xy,1) 
    circle3(xy(i,1), xy(i,2), r); 
end 
hold off 

enter image description here

0

稍作修改代碼@drorco使我想界的肯定確切數目是繪製

nCircles = 20; 
circles = zeros(nCircles ,2); 
r = 0.5; 
c=0; 

for i=1:nCircles 
%Flag which holds true whenever a new circle was found 
newCircleFound = false; 

%loop iteration which runs until finding a circle which doesnt intersect with  previous ones 
while ~newCircleFound & c<=nCircles 
    x = 0 + (5+5)*rand(1); 
    y = 0 + (5+5)*rand(1); 

    %calculates distances from previous drawn circles 
    prevCirclesY = circles(1:i-1,1); 
    prevCirclesX = circles(1:i-1,2); 
    distFromPrevCircles = ((prevCirclesX-x).^2+(prevCirclesY-y).^2).^0.5; 

    %if the distance is not to small - adds the new circle to the list 
    if i==1 || sum(distFromPrevCircles<=2*r)==0 
     newCircleFound = true; 
     c=c+1 
     circles(i,:) = [y x]; 
     circle3(x,y,r) 
    end 

end 
hold on 

結束

+0

@drorco,謝謝你看到我的微小修改。 – Matilde