You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Identical circle packing on a rectangular surface
4 views (last 30 days)
Show older comments
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.

Accepted Answer
Image Analyst
on 20 Dec 2021
Edited: Image Analyst
on 20 Dec 2021
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 Comments
Ege Arsan
on 21 Dec 2021
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
on 21 Dec 2021
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
on 3 Jan 2022
I have a follow up question. How can i delete the circles that fall outside of the constrainted area?
Image Analyst
on 3 Jan 2022
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
on 20 Jan 2022
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
on 20 Jan 2022
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
on 24 Jan 2022
Would it be possible to change the radii of a row but keep the gap to the adjacenst rows same?
Image Analyst
on 24 Jan 2022
Yes, that was the way I did it first. The radii and the grid spacing can be independent.
Ege Arsan
on 24 Jan 2022
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
on 24 Jan 2022
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
on 24 Jan 2022
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
on 24 Jan 2022
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
on 24 Jan 2022
Yes, you should have enough skills to do that. Maybe have two arrays offset vertically and horizontally by some amount.
Ege Arsan
on 24 Jan 2022
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
on 1 Feb 2022
% 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?
More Answers (0)
See Also
Categories
Find more on Surface and Mesh Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- 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)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)