Angle of rotation at a point in a deformed triangle

I have a 2D triangle which deforms with each vertex moving by some small ($\sin(x) \approx \tan(x) \approx x$) displacement vector. The displacement of any point in the triangle is linearly interpolated from the displacements at the vertices.

How can I find the rotation angle of any point in the triangle?

I want the rotation angle as a linear function of the vertex displacements and I feel that it should be (again, small displacements only). I tried the following approach but got bogged down in the enormous expressions that appear (hundreds or thousands of terms) and I'm not sure if it's even a correct way. Is there an easier way or does this simplify somehow?

• 1) Find the deformation gradient $F$ (2x2 matrix) using the displacements and the derivatives of the interpolation functions.
• 2) Find the polar decomposition $F=QS$ where $Q$ is orthogonal and $S$ is symmetric
• 3) Treat $Q$ as a rotation matrix and extract the rotation angle from it

I also tried more intuitive geometrical ways like averaging the rotation angles of all 3 vertices about the point but they don't seem to give correct looking results.

• If your displacements are interpolated linearly inside the element the deformation gradient should be constant. – nicoguaro Feb 8 '16 at 21:44

Given a small (infinitesimal) 2D displacement field $u = (u_x, u_y)$ the infinitesimal counterclockwise rotation angle $\theta$ is simply

$$\theta = \frac 12 \left ( \frac{\partial u_y}{\partial x} - \frac{\partial u_x}{\partial y} \right )$$

In general, for $n$ dimensional displacement fields $u\in\mathbb{R}^n$ it can be shown that the infinitesimal rotation is described by the skew symmetric part of the Jacobian: $$\mathbf{J} = \frac{\partial(u_1,\dots,u_n)}{\partial(x_1,\dots,x_n)}$$ i.e. $$\mathbf{\Omega} = \frac12 \left ( \mathbf{J} - \mathbf{J}^T \right)$$ This is linked to the well known fact that $\mathrm{so}(n)$ (the skew symmetric square real matrices) form the Lie algebra associated to the special orthogonal group $\mathrm{SO}(n)$ (real orthogonal matrices with determinant 1).

As already noted in another answer, $\frac{\partial u_i}{\partial x_j}$ can be easily computed from the derivatives of the shape functions and the nodal displacement values.

Edit

For linear shape functions, the Jacobian is constant. This means that $\Delta u = \mathbf{J} \Delta x$, where $\Delta u$, $\Delta x$ are the differences of displacement and coordinates, respectively, evaluated at two distinct points inside the element. If you choose two nodes, then $\Delta u$ is the difference of the nodal displacements, while $\Delta x$ is the vector representing the corresponding edge of the element. For triangles and tetrahedra is it therefore possible (explicit formula left as an exercise) to easily compute the requested quantity directly from nodal coordinates and nodal displacements.

Your approach seems to be correct, but you shouldn't be getting caught up in "hundreds to thousands" if you're doing it in a reasonable way. In case you're caught up in the mechanics of it, here's the key parts of your process laid out in a little bit more detail. I'm assuming that you can compute the deformation gradient, since you haven't provided any details about how you're interpolating.

1) Compute deformation gradient $\mathbf{F}$

2) Compute the polar decomposition: $\mathbf{F} = \mathbf{RU}$.

2a) Find eigenvalues and eigenvectors of $\mathbf{C} = \mathbf{F}^T \mathbf{F}$. This tensor has the same eigenvectors $\{\mathbf{v}_1, \mathbf{v}_2\}$ as $\mathbf{U}$, and its eigenvalues $\{\lambda_1^2, \lambda_2^2\}$ are the squares of the eigenvalues of $\mathbf{U}$. You seem to be working with 2x2 deformation gradients, so this should again be pretty easy.

2b) Reconstruct $\mathbf{U}$ using the spectral theorem (https://en.wikipedia.org/wiki/Spectral_theorem). $$\mathbf{U} = \sum_i \lambda_i \;\mathbf{v}_i \otimes \mathbf{v}_i$$

3) Solve for $\mathbf{R} = \mathbf{U}^{-1}\mathbf{F}$. Again, 2x2 matrices make this pretty easy.

4) Profit (aka: post-process $\mathbf{R}$ however you'd like).

As @nicoguaro has noted in a comment above, $\mathbf{F}$ will be constant within the triangle if you have linear interpolation functions, so you would only need to compute this angle of rotation multiple times if you use higher-order interpolation.

• That agrees with what I did. I assume your sum formula for U is the same as V Lambda V^T where V has an eigenvector in each column and Lambda has their eigenvalues on the diagonal. The reason for the complexity was doing it all symbolically so as to get the result as a function of vertex displacements. I used Maxima which perhaps wasn't simplifying very well though. – user1318499 Feb 9 '16 at 9:59
• The polar decomposition of the deformation gradient is only necessary for finite rotations. Under the small rotation/small strain assumption the infinitesimal rotation angles are the skew-symmetric part of $\mathbf{J} = \mathbf{F}-\mathbf{I}$, or $\mathbf{\Omega} = \frac12 (\mathbf{J} - \mathbf{J}^T)$. – Stefano M Feb 9 '16 at 18:06
• Yeah, but it doesn't hurt to throw the whole kitchen sink at it and understand the more general case, especially for 2x2 matrices where the computational effort is negligible. – Tyler Olsen Feb 9 '16 at 20:47

A much simpler formula is $$\theta = {1 \over 2} \nabla \times u$$ Where $u$ is displacement. The derivatives of $u$ are obtained multiplying elements of the strain-displacement matrix (p8 here) by components of $u$.

EDIT clarifications:

$u$ is a 3D field but since the question is 2D, one component is always zero.

$\nabla \times$ means curl

$\theta$ is a vector whose magnitude is the rotation angle. In 2D, it must be parallel to the plane normal so only that component is the angle and the other two are zero.

• Your formula is not very clear. If $\nabla \times u$ is the divergence of $u$ then it is wrong. If you intend the curl, then it is correct provided that you embed the 2D displacement field in a 3D space, and note that $\theta$ is the only non vanishing component of the curl vector. – Stefano M Feb 9 '16 at 18:23