You can use my spheresegmentvolume utility to solve this. It is on the file exchange.
The idea is, if two spheres intersect, then you can compute the volume of TWO spherical caps. The intersected volume is the sum of those two caps.
For example, consider two spheres, of different radii and centers, but such that the spheres do intersect, with some finite volume.
I'll be arbitrary here for my example. Suppose sphere1 has center [0 0 0], with a radius of 2. I'll create sphere 2 with a center at [4,0,0]. and a radius of 3.
The distance between centers is thus 4 units, and the sum of the radii is 5, which is greater than the distance between centers. So there is a clear intersection between the two spheres. Had the sum of the radii been smaller than the distance between centers, then no intersection could exist.
As you can also appreciate, as long as one of the spheres is not entirely inside the other, then the surfaces of the two spheres will always intersect in a circle. You can test to see if either sphere lives entirely inside the other easily enough too. In that case, the volume of intersection will be just the volume of the smaller sphere.
A non-trivial intersection volume can now be visualized as the sum of two spherical caps.
We can reduce the problem simply to this case, where there are two spheres, separated by a distance D. The distance is all that matters. So I will arbitrarily put one sphere centered at the origin, thus [0,0,0], and the second sphere centered at the point [D,0,0].
The equations of those two spheres are
x^2 + y^2 + z^2 = R1^2
(x-D)^2 + y^2 + z^2 = R2^2
Now we wish to find the plane of intersection of the spheres, IF there is some non-trivial intersection at all. So just subtract the sphere equations. This yields a simple equation, where many terms drop out.
-2*D*x = R2^2 - R1^2 - D^2
Solving for x, we can then find the location in x of the plane of intersection.
x = (D^2 - R2^2 + R1^2)/(2*D)
This is implemented in the code below. As I said, it requires ONLY knowledge of the radii and the distance between centers.
function V = sphereintersectvolume(D,R1,R2)
if any([D,R1,R2] < 0)
error('all radii and distances should in general be non-negative numbers.')
Rmin = min(R1,R2);
Rmax = max(R1,R2);
if D > (Rmin + Rmax)
V = 0;
elseif Rmax >= (D + Rmin)
V = 4/3*pi*Rmin^3;
X = (D^2 - Rmax^2 + Rmin^2)/(2*D);
V = spheresegmentvolume([X,Rmin],3,Rmin) + spheresegmentvolume([D - X,Rmax],3,Rmax);
Does this work? Of course. Lets try it out. I'll consider two spheres here, with radii 2 and 3. Now, assume that we start with the circles centers very close together.
If the circles have centers that are no larger than 1 unit apart, then the intersection volume is just the volume of the smaller sphere. That is because the difference in radii is 1 unit here.
Circles that are farther apart than 5 units in this case will have a null intersection. So, as the distance moves from 0 to 5 units and above here, we should see the volume of intersection decrease from 33.5103216382911 (the volume of the smaller sphere) to zero.
Dlist = [0.1 0.99 1.01 1.5 1.99 2.01 2.5 2.99 3 3.01 4 4.99 5 6];
for D = Dlist
As you can see in the test, that is exactly what happens. In this case, if the distance was no larger than 1, the volume is that of the smaller sphere. If the distance is larger than 5=2+3, then the volume is zero.