Clear Filters
Clear Filters

Random deposition of balls in a 2D grayscale image with avoiding the overlap as much as I can

4 views (last 30 days)
I have a code to generate balls ( one size or different sizes ). the balls have to be deposited in a random way, but at the same time I coud'nt avoid the overlap between the balls. How can I modified this code so I can generate randome packing balls avoiding the balls overlap as much as I can? Here is the code:
% Seed the random number generator for reproducibility
rng(42);
t1 = cputime;
Kbn = 1.2; % Lowball number estimate
smallColor = 0; % Four different colors: 0, 0.3, 0.6, 1
imageCut = 2048; % Image size we need, 2048x2048 pixels
BoxSize = ceil(imageCut * 1.2); % Model size, 1.2 times the image size
x_min = 1;
z_min = 1;
x_max = BoxSize;
z_max = BoxSize;
R_small = 90; % Radius of the small ball
ballNum = ceil((x_max/R_small/2)^2*Kbn); % Lowball number estimate
ballNum2 = ballNum; % Real ball number needed
% Generate ball positions
list = zeros(ballNum, 3);
for i = 1:ballNum
x_pos = x_min + (x_max - x_min) * rand; % Random x position within the container boundaries
z_pos = z_min + (z_max - z_min) * rand; % Random z position within the container boundaries
% Update the list matrix with the calculated x and z positions.
list(i, 1) = x_pos;
list(i, 2) = z_pos;
list(i, 3) = R_small; % Using only one ball size.
end
% Adjust positions to reduce overlaps
minSeparation = R_small * 2.3; % Minimum separation between ball centers
list = adjustBallPositions(list, minSeparation);
% Create the image with balls placed randomly
A1 = ones(x_max, z_max); % Create a blank image with all pixels set to 1 (white)
for i = 1:ballNum
for d = z_min:z_max
for t = x_min:x_max
if t > 0 && t <= x_max && d > 0 && d <= z_max && round(sqrt((t - list(i, 1))^2 + (d - list(i, 2))^2)) <= list(i, 3)
if list(i, 3) == R_small
A1(d, t) = smallColor;
end
continue
end
end
end
end

Answers (1)

Manas
Manas on 3 Oct 2023
Hello Wurood,
I understand that you want to write a MATLAB program that can generate an image with balls of varying sizes distributed randomly and you are facing trouble preventing the balls from overlapping.
I infer from the code you provided that you are first generating the ball positions and then checking if there are any overlaps. This approach might be more complex to implement. Instead, a simpler approach could be iteratively generating a new ball and adding it to the list only If there are no overlaps in the configuration of the balls in the image at the current iteration.
Here is a sample implementation of the above logic, I am using the same variables as declared by you in the beginning of the shared code.
% Generate ball positions
list = zeros(ballNum, 3);
for i = 1:ballNum
x_pos = x_min + (x_max - x_min) * rand; % Random x position within the container boundaries
z_pos = z_min + (z_max - z_min) * rand; % Random z position within the container boundaries
% Check for overlap with balls at the current iteration
overlap = true;
while overlap
overlap = false;
for j = 1:i-1
distance = sqrt((x_pos - list(j, 1))^2 + (z_pos - list(j, 2))^2);
if distance < (R_small + list(j, 3)) * minSeparation
overlap = true;
x_pos = x_min + (x_max - x_min) * rand; % Generate new x position
z_pos = z_min + (z_max - z_min) * rand; % Generate new z position
break;
end
end
end
% Update the list matrix with the calculated x and z positions.
list(i, 1) = x_pos;
list(i, 2) = z_pos;
list(i, 3) = R_small; % Using only one ball size.
end
Other approaches to consider are the “Packing Circles algorithm and “Disk Packing Algorithm”. You can learn more about circle packing from this Wikipedia Page: https://en.wikipedia.org/wiki/Circle_packing
Hope this helps!

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!