Skip to content

Instantly share code, notes, and snippets.

@kennyalive
Last active July 10, 2022 04:16
Show Gist options
  • Select an option

  • Save kennyalive/0dc6a932feab8a728feca4ecc326fa65 to your computer and use it in GitHub Desktop.

Select an option

Save kennyalive/0dc6a932feab8a728feca4ecc326fa65 to your computer and use it in GitHub Desktop.
Inverse of translate+rotate+scale matrix
// This implementation does not support shear transform.
// Not-uniform scale is supported.
//
// If you need to support shear then 'true' matrix inversion algorithm
// shoudl be used, for example, gaussian elimination will work.
//
Matrix3x4 get_inverse_transform(const Matrix3x4& m)
{
Vector3 scale = get_scale_from_transform(m);
Vector3 inv_scale = Vector3(1) / scale;
Vector3 x_axis = inv_scale.x * m.get_column(0);
Vector3 y_axis = inv_scale.y * m.get_column(1);
Vector3 z_axis = inv_scale.z * m.get_column(2);
Vector3 origin = m.get_column(3);
Matrix3x4 m_inv;
m_inv.set_row(0, inv_scale.x * Vector4(x_axis, -dot(x_axis, origin)));
m_inv.set_row(1, inv_scale.y * Vector4(y_axis, -dot(y_axis, origin)));
m_inv.set_row(2, inv_scale.z * Vector4(z_axis, -dot(z_axis, origin)));
return m_inv;
}
Vector3 get_scale_from_transform(const Matrix3x4& m)
{
Vector3 scale;
for (int i = 0; i < 3; i++) {
float axis_length = m.get_column(i).length();
ASSERT(axis_length != 0.f);
// If scale has small deviation from 1.0 then assume it's due to
// rounding error and in that case force scale to be exactly 1.0.
scale[i] = (std::abs(axis_length - 1.f) < 1e-6f) ? 1.f : axis_length;
}
return scale;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment