Dihedral angle defined by four points (i.e. three vectors)

1
2
3
4
5
6
7
import numpy

def dihedral(coord0, coord1, coord2, coord3):
    b = coord2 - coord1
    u = np.cross(b, coord1 - coord0)
    w = np.cross(b, coord2 - coord3)
    return np.arctan2(np.cross(u, w).dot(b), u.dot(w) * np.linalg.norm(b))
\[\begin{aligned} \textbf{coord}_{i} &\in \mathbb{R}^{3} \\ \mathbf{b}_{ij} &= \textbf{coord}_{j} - \textbf{coord}_{i} \\ \mathbf{u} &= \mathbf{b}_{12} \times \mathbf{b}_{01} = - \mathbf{b}_{01} \times \mathbf{b}_{12} \\ \mathbf{w} &= \mathbf{b}_{12} \times \mathbf{b}_{32} = -\mathbf{b}_{12} \times \mathbf{b}_{23} \\ \cos\theta &= \frac{\mathbf{u} \cdot \mathbf{w}}{\lvert \mathbf{u} \rvert \lvert \mathbf{w} \rvert} \\ \sin\theta &= \frac{(\mathbf{u}\times\mathbf{w}) \cdot \mathbf{b}_{12}}{\lvert \mathbf{u} \rvert \lvert \mathbf{w} \rvert \lvert \mathbf{b}_{12} \rvert} \\ \tan\theta &= \frac{\sin\theta}{\cos\theta} = \frac{(\mathbf{u}\times\mathbf{w}) \cdot \mathbf{b}_{12}}{\mathbf{u} \cdot \mathbf{w}} \lvert \mathbf{b}_{12} \rvert \end{aligned}\]