util/matrix: add matrix_invert()

This commit is contained in:
Simon Ser 2025-01-27 17:54:55 +01:00
parent 9dbf5b9f6b
commit 420b60f203
2 changed files with 31 additions and 0 deletions

View File

@ -39,4 +39,11 @@ void wlr_matrix_project_box(float mat[static 9], const struct wlr_box *box,
void matrix_projection(float mat[static 9], int width, int height,
enum wl_output_transform transform);
/**
* Compute the inverse of a matrix.
*
* The matrix needs to be inversible.
*/
void matrix_invert(float out[static 9], float m[static 9]);
#endif

View File

@ -1,3 +1,4 @@
#include <assert.h>
#include <string.h>
#include <wayland-server-protocol.h>
#include <wlr/util/box.h>
@ -139,3 +140,26 @@ void wlr_matrix_project_box(float mat[static 9], const struct wlr_box *box,
wlr_matrix_multiply(mat, projection, mat);
}
void matrix_invert(float out[static 9], float m[static 9]) {
float a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5], g = m[6], h = m[7], i = m[8];
// See: https://en.wikipedia.org/wiki/Determinant
float det = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h;
assert(det != 0);
float inv_det = 1 / det;
// See: https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3_%C3%97_3_matrices
float result[] = {
inv_det * (e*i - f*h),
inv_det * -(b*i - c*h),
inv_det * (b*f - c*e),
inv_det * -(d*i - f*g),
inv_det * (a*i - c*g),
inv_det * -(a*f - c*d),
inv_det * (d*h - e*g),
inv_det * -(a*h - b*g),
inv_det * (a*e - b*d),
};
memcpy(out, result, sizeof(result));
}