我有一个给定的区域(让我们说1000 x 1000),我想在这个区域放置圆圈,并满足以下要求:
我想用matlab实现一个代码。到目前为止,我已经完成了这段代码,为简单起见,它只包含一个半径值:
%% Area
perix=1000;
periy=1000;
%Number of circles
numbercircles=100;
radii(1:numbercircles)=70
%% Placing Circles
%first circle
xi=rand*perix; % array for storing x-values of circle centers
yi=radii(1); %array for storing y-values of circle centers
radiusarray=[radii(1)] ; %array for storing radii
plot(sin(linspace(0,2*pi,100))*radii(1)+xi,cos(linspace(0,2*pi,100))*radii(1)+yi);
hold on
axis([0 perix 0 perix])
% Idea:
%* Step 1: Random x coordinate for each circle middle point, y-coordinate at
% the top of the area, y_init=periy, and given radius.
%* Step 2: Lower y coordinate with constant x-coordinate until the distance to
%neighbour spheres is lower than the combined radii of those spheres.
%* Step 3: Move sphere on the x-axis to decrease the distance and further
%decrease the y-value if possible.
for lauf=2:numbercircles;
disp(numbercircles-lauf)
deltaz=10;
%% Step 1
% random x coordinate of sphere
x1=rand*100;
% y coordinate of circle is on the edge of the area and will be
% lower in the following
y1=periy;
Radnew=radii(lauf);
%% Step 2
%distance to other circle
d=min([sqrt((xi-x1).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi+perix)-x1).^2+(yi-y1).^2-(Radnew+radiusarray)) sqrt(((xi-perix)-x1).^2+(yi-y1).^2)-(Radnew+radiusarray)]);
while deltaz > 1e-4
%lower till y1=Radnew or distance to other spheres < 2*Rad
while ((y1>Radnew) & (d > deltaz))
%number=number+1
% lower y1
% if a<2
% deltaz
% end
y1=y1-deltaz;
% recalculate distance to all other spheres
d=min([sqrt((xi-x1).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi+perix)-x1).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi-perix)-x1).^2+(yi-y1).^2)-(Radnew+radiusarray)]);
end;
dmaxakt=d;
%adjust position in x direction and y direction: Increasing
%x coordinate iteratively in small steps
if (y1>Radnew)
xz(1)=x1+deltaz*rand;
if xz(1)>perix
xz(1)=x1-perix;
elseif xz(1)<0
xz(1)=x1+perix;
end;
dz(1)=min([sqrt((xi-xz(1)).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi+perix)-xz(1)).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi-perix)-xz(1)).^2+(yi-y1).^2)-(Radnew+radiusarray)]);
xz(2)=x1-deltaz*rand;
if xz(2)>perix
xz(2)=x1-perix;
elseif xz(1)<0
xz(2)=x1+perix;
end;
dz(2)=min([sqrt((xi-xz(2)).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi+perix)-xz(2)).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi-perix)-xz(2)).^2+(yi-y1).^2)-(Radnew+radiusarray)]);
%determine which distance z is the largest
vmax=find(max(dz)==dz);
%set the x-value to the value which belongs to the largest
%distance
x1=xz(vmax(1));
end;
%calculate new distance
d=min([sqrt((xi-x1).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi+perix)-x1).^2+(yi-y1).^2)-(Radnew+radiusarray) sqrt(((xi-perix)-x1).^2+(yi-y1).^2)-(Radnew+radiusarray)]);
if ((d>dmaxakt) & (y1>Radnew))
dmaxakt=d;
else
deltaz=deltaz*1e-1;
end;
end;
% if (y1<1e-5)
% y1=rand;
% end;
%last check: test if y-coordinate is still in the area
if (y1<periy-Radnew)
%Assembling the arrays for the circle places
xi=[xi x1];
yi=[yi y1];
radiusarray=[radiusarray Radnew];
end;
%Plotting
%zeit(lauf)=cputime-t;
plot(sin(linspace(0,2*pi,20))*Radnew+x1,cos(linspace(0,2*pi,20))*Radnew+y1);
%plot(sin(linspace(0,2*pi,20))*Rad1+x1+perix,cos(linspace(0,2*pi,20))*Rad1+y1);
%plot(sin(linspace(0,2*pi,20))*Rad1+x1-perix,cos(linspace(0,2*pi,20))*Rad1+y1);
hold on
axis([0 perix 0 perix])
pause(0.0001);
saveas(gcf, 'circle.png')
end;
代码基本上采用初始x坐标和最大y坐标,并降低y坐标直到检测到重叠。然后修改x坐标和y坐标以实现高密度的圆。 该代码的问题在于它非常慢,因为在每个循环中降低y坐标的距离减小,这意味着降低球体的时间可能非常长。如果有人能想出如何提高此代码的速度,我将不胜感激。
答案 0 :(得分:0)
不确定这是否有帮助,但我在您使用探查器发布时检查了您的代码,它说98%的时间是保存.png文件
第111行/ saveas(gcf,'circle.png')/ 99 / 47.741s / 98.4%
每次绘制新圆圈或只是最后一个圆圈时,您想要一张照片吗?在梯形情况下,只需将'saveas(...)'放在最后一端,并且caluclation降低到1%的时间