simkit.rotation_strain_coordinates#
Rotation–strain (RS) coordinates via Jacobian fitting.
Splits a per-element deformation gradient F = I + grad u into a rotation
R and a symmetric stretch S. The rotation is taken from the linear
field’s axis-angle (the axial vector of the antisymmetric part of grad u)
and turned into a finite rotation by the matrix exponential (Rodrigues). The
rotation–strain target Y = R @ S - I keeps both the rotation and the
strain, and vertex displacements reproducing Y in Jacobian space are fit
using a precomputed factorization.
Classes#
Precompute for fitting displacements to rotation-only Jacobian targets. |
Functions#
|
Map a displacement field to rotation–strain coordinates. |
Module Contents#
- class simkit.rotation_strain_coordinates.RSPrecompute(X: numpy.ndarray, T: numpy.ndarray, pinned: numpy.ndarray | None = None)#
Precompute for fitting displacements to rotation-only Jacobian targets.
Builds the deformation Jacobian
J, volume-weighted normal equations, and a sparse factorization ofJ^T Vol J + H_pin.- Parameters:
X (np.ndarray (n, dim)) – Rest vertex positions.
T (np.ndarray (nt, simplex_size)) – Mesh simplices.
pinned (np.ndarray, optional) – Pinned vertex indices. If
None, pins vertices near the mesh mean.
- T#
Mesh simplices.
- Type:
np.ndarray (nt, simplex_size)
- J#
Deformation Jacobian (membrane or solid).
- Type:
scipy.sparse matrix
- K#
Volume-weighted transpose
J^T Vol.- Type:
scipy.sparse matrix
- factorization#
Sparse solve handle for the penalized normal system.
- Type:
callable
- X#
- T#
- J#
- K#
- factorization#
- fit_displacements_to_jacobian(Y: numpy.ndarray) numpy.ndarray#
Solve for vertex displacements whose Jacobian matches
Y.- Parameters:
Y (np.ndarray (, dim, dim) or (, 3, 2)) – Per-element rotation targets (flattened internally).
- Returns:
u – Fitted displacement vector.
- Return type:
np.ndarray (n*dim, 1)
- simkit.rotation_strain_coordinates.rotation_strain_coordinates(X: numpy.ndarray, T: numpy.ndarray, u: numpy.ndarray, pinned: numpy.ndarray | None = None, pre: RSPrecompute | None = None, return_pre: bool = True) numpy.ndarray | Tuple[numpy.ndarray, RSPrecompute]#
Map a displacement field to rotation–strain coordinates.
Decomposes
F = I + grad uinto a rotationRand a symmetric stretchS = I + sym(grad u).Ris the matrix exponential of the linear field’s axis-angle (the axial vector of the antisymmetric part ofgrad u). Sets the rotation–strain targetY = R @ S - Iand fitsu_rssoJ u_rs ≈ Y.- Parameters:
X (np.ndarray (n, dim)) – Rest vertex positions.
T (np.ndarray (nt, simplex_size)) – Mesh simplices. Must be triangles for 2D, or tetrahedra for 3D.
u (np.ndarray (n, dim) or (n*dim,)) – Input displacement field.
pinned (np.ndarray, optional) – Pinned vertex indices passed to
RSPrecomputeifpreisNone.pre (RSPrecompute, optional) – Reusable precompute. Built from
(X, T, pinned)whenNone.return_pre (bool, optional) – If
True, return(u_rs, pre); otherwise onlyu_rs.
- Returns:
u_rs (np.ndarray (n, dim)) – Rotation–strain displacement coordinates.
pre (RSPrecompute, optional) – Precompute object (only if
return_preisTrue).