如何在C语言中求解仅含平移与旋转的欧几里得矩阵(含OpenGL场景下无缩放的4x3矩阵)的逆矩阵?
Great question—this is a staple in graphics programming, and since we're only dealing with rotation and translation (no scaling or shearing), we can leverage orthogonal matrix properties to do this efficiently, no heavy Gaussian elimination required.
1. Euclidean Matrix Inversion (General 3D Case: 4x4 Homogeneous Matrix)
First, let's recall the structure of a 3D Euclidean transformation matrix (stored in OpenGL's standard column-major order):
[ r00 r01 r02 tx ] [ r10 r11 r12 ty ] [ r20 r21 r22 tz ] [ 0 0 0 1 ]
- The top-left 3x3 submatrix
Ris a rotation matrix—a special orthogonal matrix, which means its inverse is simply its transpose (R⁻¹ = Rᵀ). - The last column
[tx, ty, tz, 1]holds the translation vectort.
How to Compute the Inverse
The inverse matrix undoes the original transformation, so it needs two key steps:
- Rotate back: Replace the rotation submatrix
Rwith its transpose. - Translate back: Calculate the new translation vector as
-Rᵀ * t—this reverses the original translation after undoing the rotation.
C Code Implementation (Column-Major 4x4 Matrix)
#include <math.h> // Inverts a 4x4 Euclidean matrix (rotation + translation only, column-major) void invert_euclidean_4x4(const float* mat, float* inv_mat) { // Step 1: Transpose the 3x3 rotation submatrix inv_mat[0] = mat[0]; inv_mat[4] = mat[1]; inv_mat[8] = mat[2]; inv_mat[1] = mat[4]; inv_mat[5] = mat[5]; inv_mat[9] = mat[6]; inv_mat[2] = mat[8]; inv_mat[6] = mat[9]; inv_mat[10] = mat[10]; // Step 2: Calculate inverse translation: -R^T * t float tx = mat[12], ty = mat[13], tz = mat[14]; inv_mat[12] = -(inv_mat[0] * tx + inv_mat[1] * ty + inv_mat[2] * tz); inv_mat[13] = -(inv_mat[4] * tx + inv_mat[5] * ty + inv_mat[6] * tz); inv_mat[14] = -(inv_mat[8] * tx + inv_mat[9] * ty + inv_mat[10] * tz); // Step 3: Set the homogeneous last row (always unchanged) inv_mat[3] = 0.0f; inv_mat[7] = 0.0f; inv_mat[11] = 0.0f; inv_mat[15] = 1.0f; }
2. Inverting a 4x3 Matrix for OpenGL (No Scaling)
In OpenGL, 4x3 matrices are a space-saving alternative to 4x4 matrices—they omit the redundant last row [0,0,0,1] from the homogeneous matrix. For our use case (rotation + translation only), the matrix is stored as 12 floats (column-major) and looks like this:
mat[0] = r00, mat[1] = r01, mat[2] = r02, mat[3] = tx mat[4] = r10, mat[5] = r11, mat[6] = r12, mat[7] = ty mat[8] = r20, mat[9] = r21, mat[10] = r22, mat[11] = tz
Each row contains 3 rotation elements plus 1 translation element.
How to Compute the Inverse
The logic mirrors the 4x4 case—we just skip handling the redundant last row:
- Transpose the 3x3 rotation submatrix.
- Calculate the inverse translation as
-Rᵀ * t.
C Code Implementation (Column-Major 4x3 Matrix)
// Inverts a 4x3 OpenGL matrix (rotation + translation only, column-major) void invert_opengl_4x3(const float* mat, float* inv_mat) { // Step 1: Transpose the 3x3 rotation submatrix inv_mat[0] = mat[0]; inv_mat[4] = mat[1]; inv_mat[8] = mat[2]; inv_mat[1] = mat[4]; inv_mat[5] = mat[5]; inv_mat[9] = mat[6]; inv_mat[2] = mat[8]; inv_mat[6] = mat[9]; inv_mat[10] = mat[10]; // Step 2: Calculate inverse translation: -R^T * t float tx = mat[3], ty = mat[7], tz = mat[11]; inv_mat[3] = -(inv_mat[0] * tx + inv_mat[1] * ty + inv_mat[2] * tz); inv_mat[7] = -(inv_mat[4] * tx + inv_mat[5] * ty + inv_mat[6] * tz); inv_mat[11] = -(inv_mat[8] * tx + inv_mat[9] * ty + inv_mat[10] * tz); }
Quick Sanity Check
Multiply the original matrix by its inverse—you should get the identity matrix (or extremely close, accounting for floating-point precision).
内容的提问来源于stack exchange,提问作者Charles Lohr

