Identical circle packing on a rectangular surface
4 次查看(过去 30 天)
显示 更早的评论
Ege Arsan
2021-12-20
Dear all,
i need to pack identical circles on a certain rectangular surface (e. g. figure). I know that there isn't any general solution to this problem but i wanted to ask anyway to have a starting point.

采纳的回答
Image Analyst
2021-12-20
编辑:Image Analyst
2021-12-20
See circle packing tag on the right hand side of this screen.
Here's a start:
radius = 20;
rows = 480;
columns = 640;
xc = 1 : radius*2 : columns;
yc = 1 : radius*2 : rows;
[x, y] = meshgrid(xc, yc);
% Shift every other row by a radius
x(2:2:end, :) = x(2:2:end, :) + radius;
numCircles = length(x(:))
radii = radius * ones(numCircles, 1);
viscircles([x(:), y(:)], radii, 'Color', 'r')
19 个评论
Ege Arsan
2021-12-21
Thank you so much!
I have a follow up question. Would it be possible to turn these circles into cylinders? Or should I use the "cylinder()" and start from scratch?
Image Analyst
2021-12-21
I don't know - try it.
And as you probably figured out, you'll need to adjust the radius. Once the circles in alternate rows have been shifted, they no longer touch. To get them to touch you'll need to have the new radius be sqrt(5)/2 times the old radius.
gridSpacing = 20;
rows = 480;
columns = 640;
scalingFactor = sqrt(5) / 2;
xc = 1 : scalingFactor * gridSpacing*2 : columns;
yc = 1 : gridSpacing*2 : rows;
[x, y] = meshgrid(xc, yc);
% Shift every other row by a radius
x(2:2:end, :) = x(2:2:end, :) + gridSpacing;
numCircles = length(x(:))
numCircles = 180
radii = scalingFactor * gridSpacing * ones(numCircles, 1);
viscircles([x(:), y(:)], radii, 'Color', 'r')

ans =
Group with properties:
Children: [2×1 Line]
Visible: on
HitTest: on
Show all properties
Ege Arsan
2022-1-3
I have a follow up question. How can i delete the circles that fall outside of the constrainted area?
Image Analyst
2022-1-3
Just get their indexes and set those indexes of both arrays to null to eliminate them
% Turn into column vectors:
x = x(:);
y = y(:);
% Find out which centers are less than x1 or more than x2
% or y < y1 or y > y2
badIndexes = (x < x1) | (x > x2) | (y < y1) | (y > y2);
x(badIndexes) = [];
y(badIndexes) = [];
Ege Arsan
2022-1-20
I have a new follow up question to this.
I need to set the first circle of first two rows to null and set the last circle of following two rows also to null. In other words two rows missing the first circles and the next two rows missing the last circles. I also need to do this for the whole plot. I tried doing it by altering your example but could not succeed. Hope you can help me.
Image Analyst
2022-1-20
You probably already figured it out by now, but here is how I'd do it: set the coordinates of the circles you don't want to NaN:
% Initialization Steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
gridSpacing = 20;
rows = 480;
columns = 640;
scalingFactor = sqrt(5) / 2;
xc = 1 : scalingFactor * gridSpacing*2 : columns;
yc = 1 : gridSpacing*2 : rows;
[x, y] = meshgrid(xc, yc);
% Shift every other row by a radius
x(2:2:end, :) = x(2:2:end, :) + gridSpacing;
numCircles = length(x(:))
radii = scalingFactor * gridSpacing * ones(numCircles, 1);
subplot(3, 1, 1);
viscircles([x(:), y(:)], radii, 'Color', 'r')
title('Original with all circles')
xlim([min(x(:) - radii(1)), max(x(:) + radii(1))])
axis square
grid on;
% Now get rid of first two circles in rows 1&2, 5&6, 9&10, etc. by setting those values to nan
% Row 1 (first row) is considered to be the bottom row (lowest y value).
x(1:4:end, 1) = nan;
x(2:4:end, 1) = nan;
y(1:4:end, 1) = nan;
y(2:4:end, 1) = nan;
% Now get rid of last circle in rows 3&4, 7&8, 11&12, etc. by setting those values to nan
x(3:4:end, end) = nan;
x(4:4:end, end) = nan;
y(3:4:end, end) = nan;
y(4:4:end, end) = nan;
subplot(3, 1, 2);
viscircles([x(:), y(:)], radii, 'Color', 'r')
grid on;
xlim([min(x(:) - radii(1)), max(x(:) + radii(1))])
axis square
title('New, with some circles missing')
% If you need it flipped vertically, subtract y from y max
yMax = max(y(:))
y = yMax - y;
subplot(3, 1, 3);
viscircles([x(:), y(:)], radii, 'Color', 'r')
title('New, flipped')
xlim([min(x(:) - radii(1)), max(x(:) + radii(1))])
axis square
grid on;

Ege Arsan
2022-1-24
Would it be possible to change the radii of a row but keep the gap to the adjacenst rows same?
Image Analyst
2022-1-24
Yes, that was the way I did it first. The radii and the grid spacing can be independent.
Ege Arsan
2022-1-24
I mean, can the rows have different radii? For example, first row has a radii of 20 and the second row has a radii of 10.
Ege Arsan
2022-1-24
Even if i manage to set the radii of a row smaller i am not sure how to keep the gaps to adjacent rows the same.
Image Analyst
2022-1-24
You just have separate variables for grid spacing and radii. Like this:
xGridSpacing = 200;
yGridSpacing = 100;
rows = 480;
columns = 640;
xc = 1 : xGridSpacing : columns;
yc = 1 : yGridSpacing : rows;
[x, y] = meshgrid(xc, yc);
% Shift every other row by half a grid spacing.
x(2:2:end, :) = x(2:2:end, :) + xGridSpacing / 2;
numCircles = length(x(:))
% Set up radii alternating 20, 10, 20, 10, etc.
radii = y; % Initialize
for k = 1 : 2 : length(yc)
indexes = y == yc(k);
radii(indexes) = 20;
end
for k = 2 : 2 : length(yc)
indexes = y == yc(k);
radii(indexes) = 10;
end
viscircles([x(:), y(:)], radii(:), 'Color', 'r')
axis('on', 'image')
grid on;

Ege Arsan
2022-1-24
I have obtained the following plot by deleting the circles in some rows. I need a way to make the bigger gaps in y-direction (deleted rows) variable so i want to be able to change these gap sizes. I think it has also to do with yGridspacing but it starts in the second row and repeats every 3 rows. Do you think that is possible?

Image Analyst
2022-1-24
Yes, you should have enough skills to do that. Maybe have two arrays offset vertically and horizontally by some amount.
Ege Arsan
2022-1-24
I tried to put yc in a while loop depending on an if statement to change the increment step between two values but couldn't figure out how to properly do it. Do you think it might work that way?
Ege Arsan
2022-2-1
% Inputs
Diameter = 18;
Height = 100;
rows = 685;
columns = 300;
GapWidth = 2;
GapToTop = 5;
GapToWall =3;
Distance = 20;
r = Diameter/2;
scalingFactor = sqrt(5) / 2;
gridSpacing = r/scalingFactor+GapWidth;
% Cuboid
P = [columns/2, rows/2, Height/2];
L = [columns, rows, Height];
O = P-L/2;
plot(L,O,.8,[1 1 1]);
hold on
plot3(P(1),P(2),P(3),'*k')
alpha(.01)
%Cylinder
[X,Y,Z] = cylinder(r);
Z = Z*Height;
for i = r : scalingFactor * gridSpacing*2 : columns
for ii = r : gridSpacing*8+Distance*2 : rows
surf(X+i,Y+r,Z)
end
end
for k = r+gridSpacing: scalingFactor * gridSpacing*2 : columns
for kk= r+gridSpacing*2+Distance : gridSpacing*8+Distance*2 : rows
surf(X+k,Y+kk,Z)
end
end
if Distance>0
b = 1;
else
b = 0;
end
for l = r+(scalingFactor * gridSpacing*2)*b:scalingFactor * gridSpacing*2:columns
for ll = r+gridSpacing*4+Distance : gridSpacing*8+Distance*2 : rows
surf(X+l,Y+ll,Z)
end
end
for j = r+gridSpacing:scalingFactor * gridSpacing*2:columns-Distance
for jj = r+gridSpacing*6+Distance*2 : gridSpacing*8+Distance*2 : rows
surf(X+j,Y+jj,Z)
end
end
for n = r : scalingFactor * gridSpacing*2 : columns-Distance
for nn = r+gridSpacing*8+Distance*2: gridSpacing*8+Distance*2 : rows
surf(X+n,Y+nn,Z)
end
end
axis image
alpha(.5)
view(3)
I have managed to adjust the distance between every other two rows and plotted them as cylinders. But since i did not use viscircles for that i no longer have the number of elements. Do you have any idea how i can obtain the number of these cylinders? And do you think it is possible to obtain the center coordinates of the cylinders as an output?
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Surface and Mesh Plots 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)