Capsule (Wikipedia) is a cylinder with hemispherical ends, or a sphere swept along a segment. It is defined by shaft (the length of the segment, noted \(a\)) and radius (\(r\)). The segment is always oriented along the local \(x\)-axis.


Fig. 9 Geometry of a capsule particle.

Particle of this shapes are useful, among others, in the pharmaceutical industry or geomechanics.


Fig. 10 Pharmaceutical capsules (image courtesy of wikipedia).


The volume is computed as

\[V=V_c+V_a=\frac{4}{3}\pi r^3+\pi r^2 a.\]

Inertia is the sum of caps’ (hemispheres) and shaft’s (cylinder) inertia, applying Parallel Axes Theorem along \(y\) and \(z\) axes:

\begin{align*} I_{xx}&=\rho\left[\frac{2}{5}V_c r^2 + \frac{1}{2}V_a r^2\right], \\ I_{yy}=I_{zz}&=\rho\left[\frac{83}{320}V_c r^2+V_c\left(\frac{a}{2}+\frac{3}{8}r\right)^2+\frac{1}{12}V_a(3r^2+a^2) \right]. \end{align*}

The centroid is always in the middle of the shaft due to symmetries. The radius of the bounding sphere is \(r+a/2\).

Capsule-capsule contact

This algorithm is implemented by woo.dem.Cg2_Capsule_Capsule_L6Geom. Determination of the contact is equivalent to finding minimum distance \(d\) between segments of both capsules. Each segment’s endpoints \(A_i\), \(B_i\) are computed by multiplying local \(x\)-axis by \(\pm a_i/2\). The algorithm is described in [Ebe99].

The normal overlap is based directly on the distance as


Determining contact point and normal purely geometrically would be discontinuous (small movement of the capsule would result in abrupt change); the reason is that the shaft (cylinder) is not convex and conforming contacts can be formed with other flat particles (such as Capsule or woo.dem.Wall). The algorithm determines the distance between endpoints and the opposite capsule, filters out those without geometrical overlap. There are 16 possible combinations.

If there is one overlap, the purely geometrical contact point and normal applies. Otherwise, all overlaps are assigned weight \(w_i=d_i-(r_1+r_2)\), and contact points \(\vec{c}_i\) and normals \(\vec{n}_i\) are computed normally (middle point of the segment in the intersection volume) and interpolated between as in

\begin{align*} \vec{n}&=\frac{\sum w_i \vec{n}_i }{\sum w_i}, & \vec{c}&=\frac{\sum w_i \vec{c}_i}{\sum w_i}. \end{align*}


The overlap \(u_N\) is used in conjunction with contact point and normal which may not correspond geometrically to the place where \(u_N\) occurs. This can lead to strange consequences, such as L6Geom.vel[0] not being the derivative of uN. The advantages of this approach (that the movement of the contact point and the normal is continuous, and that we still meaningfully represent the contact by one point) seem to outweight such inconveniences.

Wall-capsule contact

This algorithm is implemented by woo.dem.Cg2_Wall_Capsule_L6Geom and is similar to the capsule-capsule contact above; there is interpolation between max. two endpoints of the capsule touching the wall:


import math, woo, woo.core, woo.dem, woo.utils,
from minieigen import *


# view setup,-1,0)


Got questions? Ask at Report issues to github.