Speed up matrix operations (unit-wise, no interface is touched)
This commit is contained in:
parent
82d5743e77
commit
f5cc64ddd6
2 changed files with 92 additions and 92 deletions
|
|
@ -221,27 +221,26 @@ gimp_matrix2_identity (GimpMatrix2 *matrix)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_matrix2_mult:
|
* gimp_matrix2_mult:
|
||||||
* @matrix1: The first input matrix.
|
* @left: The first input matrix.
|
||||||
* @matrix2: The second input matrix which will be overwritten by the result.
|
* @right: The second input matrix which will be overwritten by the result.
|
||||||
*
|
*
|
||||||
* Multiplies two matrices and puts the result into the second one.
|
* Multiplies two matrices and puts the result into the second one.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gimp_matrix2_mult (const GimpMatrix2 *matrix1,
|
gimp_matrix2_mult (const GimpMatrix2 *left,
|
||||||
GimpMatrix2 *matrix2)
|
GimpMatrix2 *right)
|
||||||
{
|
{
|
||||||
GimpMatrix2 tmp;
|
gdouble r00 = right->coeff[0][0];
|
||||||
|
gdouble r01 = right->coeff[0][1];
|
||||||
|
|
||||||
tmp.coeff[0][0] = (matrix1->coeff[0][0] * matrix2->coeff[0][0] +
|
right->coeff[0][0] = (left->coeff[0][0] * r00 +
|
||||||
matrix1->coeff[0][1] * matrix2->coeff[1][0]);
|
left->coeff[0][1] * right->coeff[1][0]);
|
||||||
tmp.coeff[0][1] = (matrix1->coeff[0][0] * matrix2->coeff[0][1] +
|
right->coeff[0][1] = (left->coeff[0][0] * r01 +
|
||||||
matrix1->coeff[0][1] * matrix2->coeff[1][1]);
|
left->coeff[0][1] * right->coeff[1][1]);
|
||||||
tmp.coeff[1][0] = (matrix1->coeff[1][0] * matrix2->coeff[0][0] +
|
right->coeff[1][0] = (left->coeff[1][0] * r00 +
|
||||||
matrix1->coeff[1][1] * matrix2->coeff[1][0]);
|
left->coeff[1][1] * right->coeff[1][0]);
|
||||||
tmp.coeff[1][1] = (matrix1->coeff[1][0] * matrix2->coeff[0][1] +
|
right->coeff[1][1] = (left->coeff[1][0] * r01 +
|
||||||
matrix1->coeff[1][1] * matrix2->coeff[1][1]);
|
left->coeff[1][1] * right->coeff[1][1]);
|
||||||
|
|
||||||
*matrix2 = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -519,34 +518,36 @@ gimp_matrix3_transform_point (const GimpMatrix3 *matrix,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_matrix3_mult:
|
* gimp_matrix3_mult:
|
||||||
* @matrix1: The first input matrix.
|
* @left: The first input matrix.
|
||||||
* @matrix2: The second input matrix which will be overwritten by the result.
|
* @right: The second input matrix which will be overwritten by the result.
|
||||||
*
|
*
|
||||||
* Multiplies two matrices and puts the result into the second one.
|
* Multiplies two matrices and puts the result into the second one.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gimp_matrix3_mult (const GimpMatrix3 *matrix1,
|
gimp_matrix3_mult (const GimpMatrix3 *left,
|
||||||
GimpMatrix3 *matrix2)
|
GimpMatrix3 *right)
|
||||||
{
|
{
|
||||||
gint i, j;
|
gint i;
|
||||||
GimpMatrix3 tmp;
|
gdouble li0, li1, li2;
|
||||||
gdouble t1, t2, t3;
|
gdouble r00 = right->coeff[0][0];
|
||||||
|
gdouble r01 = right->coeff[0][1];
|
||||||
|
gdouble r02 = right->coeff[0][2];
|
||||||
|
gdouble r10 = right->coeff[1][0];
|
||||||
|
gdouble r11 = right->coeff[1][1];
|
||||||
|
gdouble r12 = right->coeff[1][2];
|
||||||
|
gdouble r20 = right->coeff[2][0];
|
||||||
|
gdouble r21 = right->coeff[2][1];
|
||||||
|
gdouble r22 = right->coeff[2][2];
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
t1 = matrix1->coeff[i][0];
|
li0 = left->coeff[i][0];
|
||||||
t2 = matrix1->coeff[i][1];
|
li1 = left->coeff[i][1];
|
||||||
t3 = matrix1->coeff[i][2];
|
li2 = left->coeff[i][2];
|
||||||
|
right->coeff[i][0] = li0 * r00 + li1 * r10 + li2 * r20;
|
||||||
for (j = 0; j < 3; j++)
|
right->coeff[i][1] = li0 * r01 + li1 * r11 + li2 * r21;
|
||||||
{
|
right->coeff[i][2] = li0 * r02 + li1 * r12 + li2 * r22;
|
||||||
tmp.coeff[i][j] = t1 * matrix2->coeff[0][j];
|
|
||||||
tmp.coeff[i][j] += t2 * matrix2->coeff[1][j];
|
|
||||||
tmp.coeff[i][j] += t3 * matrix2->coeff[2][j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*matrix2 = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -718,19 +719,15 @@ gimp_matrix3_affine (GimpMatrix3 *matrix,
|
||||||
gdouble
|
gdouble
|
||||||
gimp_matrix3_determinant (const GimpMatrix3 *matrix)
|
gimp_matrix3_determinant (const GimpMatrix3 *matrix)
|
||||||
{
|
{
|
||||||
gdouble determinant;
|
gdouble m01 = matrix->coeff[0][1];
|
||||||
|
gdouble m02 = matrix->coeff[0][2];
|
||||||
determinant = (matrix->coeff[0][0] *
|
gdouble m11 = matrix->coeff[1][1];
|
||||||
(matrix->coeff[1][1] * matrix->coeff[2][2] -
|
gdouble m12 = matrix->coeff[1][2];
|
||||||
matrix->coeff[1][2] * matrix->coeff[2][1]));
|
gdouble m21 = matrix->coeff[2][1];
|
||||||
determinant -= (matrix->coeff[1][0] *
|
gdouble m22 = matrix->coeff[2][2];
|
||||||
(matrix->coeff[0][1] * matrix->coeff[2][2] -
|
return matrix->coeff[0][0] * (m11 * m22 - m12 * m21)
|
||||||
matrix->coeff[0][2] * matrix->coeff[2][1]));
|
- matrix->coeff[1][0] * (m01 * m22 - m02 * m21)
|
||||||
determinant += (matrix->coeff[2][0] *
|
+ matrix->coeff[2][0] * (m01 * m12 - m02 * m11);
|
||||||
(matrix->coeff[0][1] * matrix->coeff[1][2] -
|
|
||||||
matrix->coeff[0][2] * matrix->coeff[1][1]));
|
|
||||||
|
|
||||||
return determinant;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -742,44 +739,40 @@ gimp_matrix3_determinant (const GimpMatrix3 *matrix)
|
||||||
void
|
void
|
||||||
gimp_matrix3_invert (GimpMatrix3 *matrix)
|
gimp_matrix3_invert (GimpMatrix3 *matrix)
|
||||||
{
|
{
|
||||||
GimpMatrix3 inv;
|
gdouble det;
|
||||||
gdouble det;
|
gdouble m00 = matrix->coeff[0][0];
|
||||||
|
gdouble m01 = matrix->coeff[0][1];
|
||||||
|
gdouble m02 = matrix->coeff[0][2];
|
||||||
|
gdouble m10 = matrix->coeff[1][0];
|
||||||
|
gdouble m11 = matrix->coeff[1][1];
|
||||||
|
gdouble m12 = matrix->coeff[1][2];
|
||||||
|
gdouble m20 = matrix->coeff[2][0];
|
||||||
|
gdouble m21 = matrix->coeff[2][1];
|
||||||
|
gdouble m22 = matrix->coeff[2][2];
|
||||||
|
|
||||||
det = gimp_matrix3_determinant (matrix);
|
/* To avoid redundant access to the coefficients, inline the determinant
|
||||||
|
* formula.
|
||||||
|
*
|
||||||
|
* See: https://gitlab.gnome.org/GNOME/gimp/-/merge_requests/880#note_1727051
|
||||||
|
*/
|
||||||
|
det = m00 * (m11 * m22 - m12 * m21)
|
||||||
|
- m10 * (m01 * m22 - m02 * m21)
|
||||||
|
+ m20 * (m01 * m12 - m02 * m11);
|
||||||
|
|
||||||
if (det == 0.0)
|
if (det == 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
det = 1.0 / det;
|
det = 1.0 / det;
|
||||||
|
|
||||||
inv.coeff[0][0] = (matrix->coeff[1][1] * matrix->coeff[2][2] -
|
matrix->coeff[0][0] = (m11 * m22 - m12 * m21) * det;
|
||||||
matrix->coeff[1][2] * matrix->coeff[2][1]) * det;
|
matrix->coeff[1][0] = - (m10 * m22 - m12 * m20) * det;
|
||||||
|
matrix->coeff[2][0] = (m10 * m21 - m11 * m20) * det;
|
||||||
inv.coeff[1][0] = - (matrix->coeff[1][0] * matrix->coeff[2][2] -
|
matrix->coeff[0][1] = - (m01 * m22 - m02 * m21) * det;
|
||||||
matrix->coeff[1][2] * matrix->coeff[2][0]) * det;
|
matrix->coeff[1][1] = (m00 * m22 - m02 * m20) * det;
|
||||||
|
matrix->coeff[2][1] = - (m00 * m21 - m01 * m20) * det;
|
||||||
inv.coeff[2][0] = (matrix->coeff[1][0] * matrix->coeff[2][1] -
|
matrix->coeff[0][2] = (m01 * m12 - m02 * m11) * det;
|
||||||
matrix->coeff[1][1] * matrix->coeff[2][0]) * det;
|
matrix->coeff[1][2] = - (m00 * m12 - m02 * m10) * det;
|
||||||
|
matrix->coeff[2][2] = (m00 * m11 - m01 * m10) * det;
|
||||||
inv.coeff[0][1] = - (matrix->coeff[0][1] * matrix->coeff[2][2] -
|
|
||||||
matrix->coeff[0][2] * matrix->coeff[2][1]) * det;
|
|
||||||
|
|
||||||
inv.coeff[1][1] = (matrix->coeff[0][0] * matrix->coeff[2][2] -
|
|
||||||
matrix->coeff[0][2] * matrix->coeff[2][0]) * det;
|
|
||||||
|
|
||||||
inv.coeff[2][1] = - (matrix->coeff[0][0] * matrix->coeff[2][1] -
|
|
||||||
matrix->coeff[0][1] * matrix->coeff[2][0]) * det;
|
|
||||||
|
|
||||||
inv.coeff[0][2] = (matrix->coeff[0][1] * matrix->coeff[1][2] -
|
|
||||||
matrix->coeff[0][2] * matrix->coeff[1][1]) * det;
|
|
||||||
|
|
||||||
inv.coeff[1][2] = - (matrix->coeff[0][0] * matrix->coeff[1][2] -
|
|
||||||
matrix->coeff[0][2] * matrix->coeff[1][0]) * det;
|
|
||||||
|
|
||||||
inv.coeff[2][2] = (matrix->coeff[0][0] * matrix->coeff[1][1] -
|
|
||||||
matrix->coeff[0][1] * matrix->coeff[1][0]) * det;
|
|
||||||
|
|
||||||
*matrix = inv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -942,30 +935,37 @@ gimp_matrix4_identity (GimpMatrix4 *matrix)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_matrix4_mult:
|
* gimp_matrix4_mult:
|
||||||
* @matrix1: The first input matrix.
|
* @left: The first input matrix.
|
||||||
* @matrix2: The second input matrix which will be overwritten by the result.
|
* @right: The second input matrix which will be overwritten by the result.
|
||||||
*
|
*
|
||||||
* Multiplies two matrices and puts the result into the second one.
|
* Multiplies two matrices and puts the result into the second one.
|
||||||
*
|
*
|
||||||
* Since: 2.10.16
|
* Since: 2.10.16
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gimp_matrix4_mult (const GimpMatrix4 *matrix1,
|
gimp_matrix4_mult (const GimpMatrix4 *left,
|
||||||
GimpMatrix4 *matrix2)
|
GimpMatrix4 *right)
|
||||||
{
|
{
|
||||||
GimpMatrix4 result = {};
|
GimpMatrix4 result = {};
|
||||||
gint i, j, k;
|
gint i, j;
|
||||||
|
gdouble li0, li1, li2, li3;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
li0 = left->coeff[i][0];
|
||||||
|
li1 = left->coeff[i][1];
|
||||||
|
li2 = left->coeff[i][2];
|
||||||
|
li3 = left->coeff[i][3];
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
for (k = 0; k < 4; k++)
|
result.coeff[i][j] = li0 * right->coeff[0][j]
|
||||||
result.coeff[i][j] += matrix1->coeff[i][k] * matrix2->coeff[k][j];
|
+ li1 * right->coeff[1][j]
|
||||||
|
+ li2 * right->coeff[2][j]
|
||||||
|
+ li3 * right->coeff[3][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*matrix2 = result;
|
*right = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@ GParamSpec * gimp_param_spec_matrix2 (const gchar *name,
|
||||||
|
|
||||||
|
|
||||||
void gimp_matrix2_identity (GimpMatrix2 *matrix);
|
void gimp_matrix2_identity (GimpMatrix2 *matrix);
|
||||||
void gimp_matrix2_mult (const GimpMatrix2 *matrix1,
|
void gimp_matrix2_mult (const GimpMatrix2 *left,
|
||||||
GimpMatrix2 *matrix2);
|
GimpMatrix2 *right);
|
||||||
|
|
||||||
gdouble gimp_matrix2_determinant (const GimpMatrix2 *matrix);
|
gdouble gimp_matrix2_determinant (const GimpMatrix2 *matrix);
|
||||||
void gimp_matrix2_invert (GimpMatrix2 *matrix);
|
void gimp_matrix2_invert (GimpMatrix2 *matrix);
|
||||||
|
|
@ -90,8 +90,8 @@ GParamSpec * gimp_param_spec_matrix3 (const gchar *name,
|
||||||
|
|
||||||
|
|
||||||
void gimp_matrix3_identity (GimpMatrix3 *matrix);
|
void gimp_matrix3_identity (GimpMatrix3 *matrix);
|
||||||
void gimp_matrix3_mult (const GimpMatrix3 *matrix1,
|
void gimp_matrix3_mult (const GimpMatrix3 *left,
|
||||||
GimpMatrix3 *matrix2);
|
GimpMatrix3 *right);
|
||||||
void gimp_matrix3_translate (GimpMatrix3 *matrix,
|
void gimp_matrix3_translate (GimpMatrix3 *matrix,
|
||||||
gdouble x,
|
gdouble x,
|
||||||
gdouble y);
|
gdouble y);
|
||||||
|
|
@ -135,8 +135,8 @@ void gimp_matrix3_transform_point (const GimpMatrix3 *matrix,
|
||||||
/*****************/
|
/*****************/
|
||||||
|
|
||||||
void gimp_matrix4_identity (GimpMatrix4 *matrix);
|
void gimp_matrix4_identity (GimpMatrix4 *matrix);
|
||||||
void gimp_matrix4_mult (const GimpMatrix4 *matrix1,
|
void gimp_matrix4_mult (const GimpMatrix4 *left,
|
||||||
GimpMatrix4 *matrix2);
|
GimpMatrix4 *right);
|
||||||
|
|
||||||
void gimp_matrix4_to_deg (const GimpMatrix4 *matrix,
|
void gimp_matrix4_to_deg (const GimpMatrix4 *matrix,
|
||||||
gdouble *a,
|
gdouble *a,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue