Assessment of the surface area of a sphere

A sphere is a common geometrical object of choice in many computational sciences used to approximate continuous, closed surfaces forming 3-D ball-like models. Concretely, in my research area - computational bioelectromagnetics and dosimetry, or in computational neuroscience for example, we often approximate the surface of the human head by using a sphere.

Even though this kind of representation of real world objects is a crude geometrical approximation, see Fig. 1 below, it allows a much simpler simulation setup due to the high symmetry of the solution domain.

round-head
Figure 1. This would have been Mona Liza had Leonardo da Vinci been a computational scientist. Jokes aside, this painting is the work by the great Fernando Botero, a Colombian figurative artist and sculptor whose signature style often depicts people and figures in hyperbolic manner.


One of the common issues in simulations is the estimation of the total surface area of a portion of the observed object. For regular spherical surfaces, this is fairly easy to do, and yet in this short essay, I will demonstrate the hard way to do it.

Let's start by calculating the area of a sphere defined by some radius, $r$, using the following closed-form expression:

$$ A = 4 \pi r^2 $$

It turns out that the area of a sphere with a radius set to $1$ amounts to $\sim12.566361$.

The closed-form expression derives from the surface integral of a tiny surface element, $dA$, on the sphere, in spherical coordinates given as:

$$ dA = r^2 \sin \theta d\theta d\phi $$

More details on the parametrization should be found elsewhere, e.g., in this very short video lecture by Khan Academy.

The overall area is obtained by integrating all these tiny surface elements for the entire domain, $\theta \in [0, 2\pi]$ and $\phi \in [0, \pi]$, and by setting the radius to a fixed value:

$$ A = \int_{0}^{2\pi}\int_{0}^{\pi}r^2 \sin \theta d\theta d\phi $$

There is no chance I will do the math by hand. I am not even sure if I know how to. I am not even sure if I own a pen and paper anymore... Rather, let's take advantage a very smart box called computer and implement Gauss quadrature, introduction of which is available on Wikipedia. In a nutshell, the above integral can be approximated as a weighted sum of each surface element at each specific point within the domain. These "specific" points, and associated weights, arise from the choice of underlying polynomials that define our domain. Here, we are going to use Legendre polynomials.

Nice, we are accurate to at least the 6th decimal, which should be satisfactory for most small-scale applications.

However, the main issue with this approach is that we have to use predefined set of sample points and weights. In real-world applications and simulations, points are unordered, random, sometimes even noisy. For irregular point clouds, we should first reconstruct the surface, and only then we can estimate the total surface area.

A common way to approach this issue, assuming that the surface is convex, is by triangulatng the surface by using the convex hull or envelope. The convex hull is the smallest convex region contating the point set which we have at our disposal, where this region is any region in which each point-pair is visible within the region itself. Important caveat is that convex hull algorithms suffer greatly, and result with invalid reconstructed regions for that matter, if there exist any kind of degenerate situations.

Now, let's first randomly generate a point cloud representing the sphere with the radius set to 1. For this, we will use the elegant method that consists of picking two values from independent uniform distributions, $a$ and $b$, and rejecting points that does not satisfy the following condition:

$$ a^2 + b^2 \leq r $$

where $r$ stands for the radius of a ball.

After, the randomly generated point cloud is forwarded to scipy.spatial.ConvexHull class, and the surface area is simply obtained by accessing the attribute scipy.spatial.ConvexHull.area.

Results are not as good as with the Gaussian-Legendre quadrature approach, but this is expected since a convex hull is nothing but a bunch of small planar polygons that reconstruct a sphere, and the sphere is inherently non-planar.

This problem can be somewhat circumvented if we generate a larger number of surface points. For example, if we set n_points argument of marsaglia function to $20000$ for example, we get a much, much better surface area estimate.

Very nice.

All this so far is very nice, simple and elegant, but I want something that is a complete opposite of that. I will now demonstrate how to compute the area of a sphere in an overly complicated way just because I want to be a cool kid who uses new fancy libraries for sport.

Here, we are going to use jax and its automatic differentiation capabilities to extract the gradients of vectors normal to the sphere in order to compute the following integral, and thus estimate the surface area:

$$ A = \int_x \int_y \sqrt{\Big(\frac{\partial z}{\partial x}\Big)^2 + \Big(\frac{\partial z}{\partial y}\Big)^2 + 1} dx dy $$

What is this integral anyway?

Well, we first have to set one of the coordinates, in this case I have chosen $z$, to be a function of other two:

$$ z = z(x, y) $$

Since we talk about a sphere here, $z$, as a function of $x$ and $y$, is defined as:

$$ z = z(x, y) = \pm \sqrt{r - x^2 - y^2} $$

where $r$, as always, stands for the radius.

This parametrization yields the definition of the position vector $\vec r$, shown in Fig. 2, written as follows:

$$ \vec r = \vec r(x, y) = x \vec i + y \vec j + z(x, y) \vec k $$
spherical-coordinates
Figure 2. The position vector connects each point of a sphere to the ball origin. Image source: https://mathworld.wolfram.com/SphericalCoordinates.html

The magnitude of the cross product of the partial derivatives of $\vec r(x, y)$ yields the vector surface element, $\vec{dA}$:

$$ \vec{dA} = \Big|\frac{\partial \vec r(x, y)}{\partial x} \times \frac{\partial \vec r(x, y)}{\partial y}\Big| $$

By following the defintion of the position vector, the partial derivatives with respect to $x$ and $y$ are respectively written as:

$$ \frac{\partial \vec r}{\partial x} = \vec i + \frac{\partial z(x,y)}{\partial x} \vec k $$

and

$$ \frac{\partial \vec r}{\partial y} = \vec j + \frac{\partial z(x,y)}{\partial y} \vec k $$

From here, it follows that

$$ \vec{dA} = \Big|\Big(\vec i + \frac{\partial z(x,y)}{\partial x} \vec k \Big) \times \Big(\vec j + \frac{\partial z(x,y)}{\partial y} \vec k\Big)\Big| = \Big|\Big(-\frac{\partial z(x, y)}{\partial x}, -\frac{\partial z(x, y)}{\partial x}, 1\Big)\Big| $$

Finally, once we define the magnitude of this expression:

$$ |\vec{dA}| = \sqrt{\Big(\frac{\partial z}{\partial x}\Big)^2 + \Big(\frac{\partial z}{\partial y}\Big)^2 + 1} $$

we finally have the reasoning behind the above mentioned surface integral.

The expression for $|\vec{dA}|$ can be separated in a following way:

$$ |\vec{dA}| = dA \cdot \vec n $$

where $\vec n$ is the vector normal to the parameterized surface element $dA = dxdy$.

Okay, so entire outlined math here basically means that if we can somehow are able to compute gradients of the normal vector in each point on our parameterized surface, we can compute the overall surface area. The parametrization of a sphere is a bit tricky for a computer to handle it because it includes square roots, so instead parametrization of an entire sphere, we are going to parametrize only a small positive portion and scale the final area estimate accordingly. Let's begin.

Alright, not bad at all!

We managed to get pretty close to the actual value of the surface area. To wrap things up, let's generate a summary table of the results obtained via 3 different numerical tecniques in comparisson to the actual target value.