我一直在使用函数文件[ret]=drawellipse(x,y,a,b,angle,steps,color,img)
。通过脚本文件调用函数以在图像中绘制随机椭圆。但是一旦我设置了随机中心点(x,y)和随机a,b,很可能会出现椭圆交点。我该如何防止交叉? (我应该画出彼此分开的椭圆)
好吧,在这里我有一个函数文件,用于检查省略号是否重叠,overlap = overlap_ellipses(x0,y0,a0,b0,angle0,x1,y1,a1,b1,angle1)
。如果两个椭圆重叠,则'overlap = 1',否则'overlap = 0'。
基于所有这些,我在命令窗口中进行了测试:
x=rand(4,1)*400; % x and y are the random coodinates for the center of ellipses
y=rand(4,1)*400;
a=[50 69 30 60]; % major axis for a and b, i intend to use random also in the future
b=[20 40 10 40]; % minor axis
angle=[30 90 45 0]; % angle of ellipse
steps=10000;
color=[255 0 0]; % inputs for another function file to draw the ellipse
img=zeros(500,500,3);
以下我想显示省略号if overlap==0
和'if overlap == 1',减少a和b,直到没有交集。最后,要简化img。
for i=1:length(x)
img=drawellipse(x(i),y(i),a(i),b(i),angle(i),steps,color,img);
end
对我来说,我很难对中间部分进行编码。我如何使用if语句获取overlap
的值以及如何使索引对应于我需要绘制的椭圆。
我测试了一下像
for k=1:(length(x)-1)
overlap = overlap_ellipses(x(1),y(1),a(1),b(1),angle(1),x(1+k),y(1+k),a(1+k),b(1+k),angle(1+k))
end
它返回
overlap=0
overlap=0
overlap=1
不是[0 0 1]。我无法弄清楚,因此陷入了这个过程。 最终的图像看起来像这个voronoi diagram of ellipses中的图片。 (任何两个椭圆之间没有交叉点)
答案 0 :(得分:3)
假设您正在将椭圆绘制成光栅图形图像,您可以计算要为椭圆绘制的像素,检查图像中的这些像素是否仍然是背景颜色,并仅在以下情况下绘制椭圆:答案是肯定的,否则拒绝它(因为其他东西,即另一个椭圆,挡路)并尝试其他x
,y
,a
和b
。
或者,您可以将图像分割成矩形(不一定是相同大小),并在每个图像中放置一个椭圆,选择x,y,a,b,使椭圆不超过其矩形 - 然后椭圆也不会重叠,但这取决于你的椭圆放置应该有多少“随机性”,这是否足够。
数学上严谨的方法是存储每个绘制椭圆的x,y,a,b,并且对于每个新椭圆,通过求解两个二次方程组,对每个椭圆进行成对检查。但是,这可能有点复杂,特别是一旦角度不是0。
编辑以响应添加的代码:您可以在循环内确定它们,而不是在循环之前修复所有x
和y
。既然您知道需要多少个省略号,而不知道需要多少省略号,则需要while
循环。您给出的测试循环可能派上用场,但您需要将所有先前的省略号与循环迭代中创建的省略号进行比较,而不是第一次。
i=1;
while (i<=4) %# or length(a), or, more elegantly, some pre-defined max
x(i) = rand*400; y(i) = rand*400; %# or take x and y as givren and decrease a and b
%# now, check overlap for given center
overlap = false;
for k=1:(i-1)
overlap = overlap || overlap_ellipses(x(i),y(i),a(i),b(i),angle(i),x(k),y(k),a(k),b(k),angle(k))
end
if (~overlap)
img = drawellipse(x(i),y(i),a(i),b(i),angle(i),steps,color,img);
i = i+1; %# determine next ellipse
end %# else x(i) and y(i) will be overwritten in next while loop iteration
end
当然,如果a
和b
是固定的,可能会发生这样的情况,即如果已经存在的椭圆不幸放置,则椭圆不适合图像尺寸,从而导致无限循环。
关于你离开中心的计划是否固定并减小椭圆的大小直到它适合:你的overlap_ellipses
方法来自哪里?也许它可以被调整为返回一个因子,一个椭圆需要缩小以适合另一个椭圆(如果它已经适合,则为1)?
答案 1 :(得分:1)
一个选项是跟踪已绘制的所有椭圆,并确保下一组[x,y,a,b]
不会产生与现有椭圆相交的新椭圆。你可以调用随机数,直到你找到一个满足条件的集合,或者一旦你有一个违反条件的集合,减少a
和/或b
的值,直到没有交集发生
答案 2 :(得分:1)
@arne.b(第一个)提出的解决方案是栅格化非重叠椭圆的好方法。
让我用一个例子说明这个想法。我将扩展我的previous answer:
%# color image
I = imread('pears.png');
sz = size(I);
%# parameters of ellipses
num = 7;
h = zeros(1,num);
clr = lines(num); %# color of each ellipse
x = rand(num,1) .* sz(2); %# center x-coords
y = rand(num,1) .* sz(1); %# center y-coords
a = rand(num,1) .* 200; %# major axis length
b = rand(num,1) .* 200; %# minor axis length
angle = rand(num,1) .* 360; %# angle of rotation
%# label image, used to hold rasterized ellipses
BW = zeros(sz(1),sz(2));
%# randomly place ellipses one-at-a-time, skip if overlaps previous ones
figure, imshow(I)
axis on, hold on
for i=1:num
%# ellipse we would like to draw directly on image matrix
[ex,ey] = calculateEllipse(x(i),y(i), a(i),b(i), angle(i), 100);
%# lets plot the ellipse (overlayed)
h(i) = plot(ex,ey, 'LineWidth',2, 'Color',clr(i,:));
%# create mask for image pixels inside the ellipse polygon
mask = poly2mask(ex,ey,sz(1),sz(2));
%# get the perimter of this mask
mask = bwperim(mask,8);
%# skip if there is an existing overlapping ellipse
if any( BW(mask)~=0 ), continue, end
%# use the mask to place the ellipse in the label image
BW(mask) = i;
end
hold off
legend(h, cellstr(num2str((1:num)','Line%d')), 'Location','BestOutside') %'
%# set pixels corresponding to ellipses using specified colors
clr = im2uint8(clr);
II = I;
for i=1:num
BW_ind = bsxfun(@plus, find(BW==i), prod(sz(1:2)).*(0:2));
II(BW_ind) = repmat(clr(i,:), [size(BW_ind,1) 1]);
end
figure, imshow(II, 'InitialMagnification',100, 'Border','tight')
注意如何按照添加椭圆的顺序执行重叠测试,因此在绘制Line1(蓝色)和Line2(绿色)之后,将跳过Line3(红色),因为它与之前的一个重叠,因此其余的......