Borrar filtros
Borrar filtros

MatLab stays on Run forever and doesn't generate image file

2 visualizaciones (últimos 30 días)
Lindee
Lindee el 3 de Jun. de 2024
Respondida: Image Analyst el 4 de Jun. de 2024
HI! I am trying to make a circle that has randomly distrubuted holes inside of it. Matlab is not responding and isn't generating the desired image file. Can you please check my code to see if this is an issue on the coding side or is Matlab just not responding.
% Define parameters
big_radius = 10 / 2; % Radius of the big circle (in micrometers)
small_radius = 3 / 2; % Radius of the small circles (in micrometers)
num_circles = 50; % Number of small circles
% Generate random positions for the small circles inside the big circle
theta = 2*pi*rand(1, num_circles); % Random angles
r = big_radius*sqrt(rand(1, num_circles)); % Random radii
x_center = r.*cos(theta); % x-coordinates of circle centers
y_center = r.*sin(theta); % y-coordinates of circle centers
% Check if small circles intersect with the boundary of the big circle
valid_indices = (x_center.^2 + y_center.^2 + small_radius^2) < big_radius^2;
% Initialize array to store valid circle centers
x_valid = zeros(1, num_circles);
y_valid = zeros(1, num_circles);
% Iterate through valid circles and adjust positions to avoid overlap
for i = 1:num_circles
if valid_indices(i)
% Check for overlap with previously placed circles
overlap = sqrt((x_valid(1:i-1) - x_center(i)).^2 + (y_valid(1:i-1) - y_center(i)).^2) < (small_radius * 2);
while any(overlap)
% If overlap, regenerate new random position
theta(i) = 2*pi*rand(); % Random angle
r(i) = big_radius*sqrt(rand()); % Random radius
x_center(i) = r(i)*cos(theta(i)); % x-coordinate of circle center
y_center(i) = r(i)*sin(theta(i)); % y-coordinate of circle center
% Check for overlap again
overlap = sqrt((x_valid(1:i-1) - x_center(i)).^2 + (y_valid(1:i-1) - y_center(i)).^2) < (small_radius * 2);
end
% Store valid circle center
x_valid(i) = x_center(i);
y_valid(i) = y_center(i);
end
end
% Plot the big circle
theta_big = linspace(0, 2*pi, 1000);
x_big = big_radius * cos(theta_big);
y_big = big_radius * sin(theta_big);
% Plot the big circle
figure;
plot(x_big, y_big, 'b', 'LineWidth', 2);
hold on;
% Plot the valid small circles
plot(x_valid(valid_indices), y_valid(valid_indices), 'ro', 'MarkerSize', 5);
axis equal;
xlabel('X (micrometers)');
ylabel('Y (micrometers)');
title('Circle with Diameter of 10 Micrometers and Randomly Distributed 3 Micrometer Circles Inside (No Overlap)');
grid on;
hold off;
% Save the plot as an image file
saveas(gcf, 'circle_with_small_circles.png');

Respuestas (2)

Voss
Voss el 3 de Jun. de 2024
"check my code to see if this is an issue on the coding side or is Matlab just not responding"
It is an issue on the coding side.
Consider the fact that the big circle is only about 11 times as big as a small circle (hole):
% Define parameters
big_radius = 10 / 2; % Radius of the big circle (in micrometers)
small_radius = 3 / 2; % Radius of the small circles (in micrometers)
num_circles = 50; % Number of small circles
big_area = pi*big_radius^2;
small_area = pi*small_radius^2;
big_area/small_area
ans = 11.1111
which means that you'll never be able to fit more than 11 holes in the big circle. (In fact the maximum number of holes that can fit is even smaller than that.)
The code is written to attempt to find 50 such holes, and to keep looking when the holes overlap, so that's what the code does: just keeps looking forever, because it's not possible to find 50 such holes.

Image Analyst
Image Analyst el 4 de Jun. de 2024
Usually when there is an infinite loop it's with a while loop that never met the condition to exit, and (importantly!) didn't have a failsafe. Your while loops do not have a failsafe to prevent an infinite loop, as all while loops should have. Let's say that you know the while loop should iterate about 1000 times, and that if it goes over 50,000, something's definitely wrong. So you must have a loop counter and a check that the loop counter does not exceed your max iteration count. Modify your loops to add a failsafe like this:
maxIterations = 50000; % Some big number that you know should never be reached.
loopCounter = 1;
while someCondition && loopCounter <= maxIterations
fprintf('Starting iteration #%d.\n', loopCounter);
% Some code to generate a new value for someCondition.
% Increment the loop counter:
loopCounter = loopCounter + 1;
end
if loopCounter >= maxIterations
warningMessage = sprintf('Loop terminated early after %d iterations', loopCounter - 1);
uiwait(warndlg(warningMessage));
end
Now, after you've made those modifications, what do you see? It should kick out after it hits the max iteration number. Does it? Why? You should check the condition for when the two loops you have should exit. Are they ever met?

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by