This page explains the geometry of the calculations in L&R and can be used to understand the source code. As far as possible the code uses similar notation to the formulas here.
We will use the following notation: An atom \(i\) has a van der Waals radius \(r_i\), the rolling sphere (or probe) has radius \(r_\text{P}\) and when these are added we get an extended radius \(R_i = r_i + r_\text{P}\). The sphere of radius \(R_i\) centered at the position of atom \(i\) represents the volume not accessible to the center of the probe. The SASA for a molecule is then obtained by calculating the non-buried surface area of the extended spheres.
The L&R algorithm calculates the surface area by slicing the protein, calculating the length of the solvent exposed contours in each slice and then adding up the length multiplied by the slice thickness.
Divide atom \(i\) into \(n\) slices, orthogonal to an arbitrary axis, of thickness \(\delta = 2R_i/n\). The position of the middle of the slice along that axis is denoted \(z\), and the center of atom \(i\), along the same axis, is at \(z_i\). In each slice, the atom is thus a circle of radius
\[R_i^\prime = \sqrt{R_i^2-(z-z_i)^2}\,.\]
These circles are either completely buried inside neighboring atoms, completely exposed, or partially exposed.
The exposed arc lengths for each atom can be calculated exactly. For each pair of atoms \(i,j\), the distance between their centers projected on the slice is \(d_{ij}\) (independent of \(z\)). If \(d_{ij} > R_i^\prime + R_j^\prime\), there is no overlap. If \(d_{ij} < R_j^\prime - R_i^\prime\) circle \(i\) is completely inside \(j\) (and the other way around). If \(d_{ij}\) lies between these two cases the angle of circle \(i\) that is buried due to circle \(j\) is
\[ \alpha = 2\arccos \bigl[({R_i^\prime}^2{\,} - d_{ij}^2 - {R_{j}^\prime}^2{\,})/(2R_i^\prime d_{ij})\bigr]. \]
If the middle point of this arc on the circle is at an angle \(\beta\), the arc spans the interval \([\beta-\alpha/2,\beta+\alpha/2]\). By adding up these arcs and taking into account any overlap between them we get the total buried angle \(\gamma\) in this slices. The exposed arc angle for this atom and slice is thus \(2\pi-\gamma\) and the total SASA of that atom
\[ A_i =R_i \delta \!\! \sum_{s\in\text{slices}} \!\! \left[2\pi-\gamma_s\right]\,. \]
The angle is multiplied by \(R_i\) (not \(R_i^\prime\)) to give the area of a conical frustum circumscribing the sphere at the slice. Finally, the total area \(A\) is the sum of all \(A_i\).
In FreeSASA, the L&R SASA calculation begins by finding overlapping spheres and storing the contacts in an adjacency list. It then iterates through all the slices of each atom and checks for overlap with adjacent atoms in each slice, and adds up the exposed arcs to calculate the atom's contribution to the SASA of the slice. The calculations for each atom are completely independent and can thus be parallelized over an arbitrary number of threads, whereas the calculation of adjacency lists has not been parallelized.