Asked by Kelly McGuire
on 12 Jan 2019

I am trying to estimate the volume of two overlapping spheres using the Monte Carlo method. One sphere (white) is centered at 1,1,1. The other sphere is centered at 2.293,1,1. The length from one sphere center to the other sphere center is 1.293. The white sphere's radius is 1.2 and the green sphere's radius is 1.8. I am trying to fill the white sphere with white '+' marks and the green sphere with green '+' marks. Any volume outside of these overlapping spheres is filled with red '+' marks. So far, my code is very close to working the way I want. However, red '+' marks are still getting in the green sphere. It doesn't look like they are placed in the white sphere. I have four questions:

1) Why are red '+' marks still getting in based on the code I am pasting here?

2) If you comment out line 57 (no red marks plotted), and then choose around 400 points, you'll notice in the plot that the marks do not fill up the green sphere, but they do fill the volume of the white sphere. Why aren't marks being placed throughout all of the green sphere?

3) What should I do about the overlapping volume region?

4) How do I then calculate the volume of the overlapping spheres compared to the non-sphere volume? Including the overlapping part of the spheres (question 2).

Code:

clc

clear

N=input('Number of points: ');

[X, Y, Z]=sphere;

a = [1 1 1 1.2; 2.293,1,1,1.8];

%Draw sphere #1

s1=surf(X*a(1,4)+a(1,1), Y*a(1,4)+a(1,2), Z*a(1,4)+a(1,3),'FaceColor', [1 1 1],'edgecolor','none','FaceAlpha',0.6);

light

axis equal

set(gca,'Color','k')

hold on

s2=surf(X*a(2,4)+a(2,1), Y*a(2,4)+a(2,2), Z*a(2,4)+a(2,3),'FaceColor', [0 1 0],'edgecolor','none','FaceAlpha',0.5);

daspect([1 1 1])

view(30,10)

xlabel('x')

ylabel('y')

zlabel('z')

x1range1 = -0.2;

x1range2 = 4.093;

y1range1 = -0.8;

y1range2 = 2.8;

z1range1 = -0.8;

z1range2 = 2.8;

hit1 = 0;

hit2 = 0;

for i = 1:N

x = (x1range2-x1range1).*rand(N,1)+x1range1;

y = (y1range2-y1range1).*rand(N,1)+y1range1;

z = (z1range2-z1range1).*rand(N,1)+z1range1;

x1=x-1;

y1=y-1;

z1=z-1;

r1=x1.^2+y1.^2+z1.^2;

x2=x-2.293;

y2=y-1;

z2=z-1;

r2=x2.^2+y2.^2+z2.^2;

ii = r1<=1.2;

jj = r2<=1.8;

hit1 = sum(ii);

hit2 = sum(jj);

plot3(x(ii), y(ii), z(ii), 'w+');

plot3(x(~ii), y(~ii), z(~ii), 'r+');

plot3(x(jj), y(jj), z(jj), 'g+');

%plot3(x(~jj), y(~jj), z(~jj), 'r+');

drawnow

end

Answer by Kelly McGuire
on 13 Jan 2019

Accepted Answer

Here is the complete working code:

clc

clear

S=input('Number of Simulations: ');

N=input('Number of points: ');

fileID = fopen('Volume.txt','w');

for k = 1:S

[X, Y, Z]=sphere;

a = [1 1 1 1.2; 2.293,1,1,1.8];

%Draw sphere #1

figure('color','white');

s1=surf(X*a(1,4)+a(1,1), Y*a(1,4)+a(1,2), Z*a(1,4)+a(1,3),'FaceColor', [1 1 1],'edgecolor','none','FaceAlpha',0.6);

light

axis equal

set(gca,'Color','k')

hold on

%Draw sphere #2

s2=surf(X*a(2,4)+a(2,1), Y*a(2,4)+a(2,2), Z*a(2,4)+a(2,3),'FaceColor', [0 1 0],'edgecolor','none','FaceAlpha',0.5);

daspect([1 1 1])

view(30,10)

xlabel('x')

ylabel('y')

zlabel('z')

% x1range1 = -0.2;

% x1range2 = 4.093;

% y1range1 = -0.8;

% y1range2 = 2.8;

% z1range1 = -0.8;

% z1range2 = 2.8;

x1range1 = -1.0;

x1range2 = 5.0;

y1range1 = -1.0;

y1range2 = 3.0;

z1range1 = -1.0;

z1range2 = 3.0;

hit1 = 0; %Points inside spheres

hit2 = 0;

for i = 1:N

%Define Box Range and Randomize Points

x = (x1range2-x1range1).*rand(N,1)+x1range1;

y = (y1range2-y1range1).*rand(N,1)+y1range1;

z = (z1range2-z1range1).*rand(N,1)+z1range1;

x1=x-1;

y1=y-1;

z1=z-1;

r1=sqrt(x1.^2+y1.^2+z1.^2);

x2=x-2.293;

y2=y-1;

z2=z-1;

r2=sqrt(x2.^2+y2.^2+z2.^2);

ii = r1<=1.2;

jj = r2<=1.8;

hit1 = sum(ii);

hit2 = sum(jj);

plot3(x(ii), y(ii), z(ii), 'w+');

%plot3(x(~ii), y(~ii), z(~ii), 'r+');

plot3(x(jj), y(jj), z(jj), 'g+');

drawnow

end

SpherePercentVolume = (hit1+hit2)/N;

Volume = ((x1range2-x1range1)*(y1range2-y1range1)*(z1range2-z1range1))*SpherePercentVolume

fprintf(fileID,'%6.3f\r\n',Volume);

end

fclose(fileID);

load Volume.txt

average = mean(Volume);

stdev = std(Volume);

fileID = fopen('AvgVolume.txt','w');

fprintf(fileID,'%6s','Average Volume: ');

fprintf(fileID,'%6.3f\r\n',average);

fprintf(fileID,'%6s','Standard Deviation: ');

fprintf(fileID,'%6.3f',stdev);

Image Analyst
on 13 Jan 2019

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.