Flutter Engine
The Flutter Engine
Functions
SkMatrixInvert.cpp File Reference
#include "src/core/SkMatrixInvert.h"
#include "include/private/base/SkFloatingPoint.h"

Go to the source code of this file.

Functions

SkScalar SkInvert2x2Matrix (const SkScalar inMatrix[4], SkScalar outMatrix[4])
 
SkScalar SkInvert3x3Matrix (const SkScalar inMatrix[9], SkScalar outMatrix[9])
 
SkScalar SkInvert4x4Matrix (const SkScalar inMatrix[16], SkScalar outMatrix[16])
 

Function Documentation

◆ SkInvert2x2Matrix()

SkScalar SkInvert2x2Matrix ( const SkScalar  inMatrix[4],
SkScalar  outMatrix[4] 
)

Computes the inverse of inMatrix, passed in column-major order. inMatrix and outMatrix are allowed to point to the same array of scalars in memory. outMatrix is allowed to be null. The return value is the determinant of the input matrix. If zero is returned, the matrix was non-invertible, and outMatrix has been left in an indeterminate state.

Definition at line 12 of file SkMatrixInvert.cpp.

12 {
13 double a00 = inMatrix[0];
14 double a01 = inMatrix[1];
15 double a10 = inMatrix[2];
16 double a11 = inMatrix[3];
17
18 // Calculate the determinant
19 double determinant = a00 * a11 - a01 * a10;
20 if (outMatrix) {
21 double invdet = sk_ieee_double_divide(1.0, determinant);
22 outMatrix[0] = a11 * invdet;
23 outMatrix[1] = -a01 * invdet;
24 outMatrix[2] = -a10 * invdet;
25 outMatrix[3] = a00 * invdet;
26 // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
27 // values is non-finite, return zero to indicate a non-invertible matrix.
28 if (!SkIsFinite(outMatrix, 4)) {
29 determinant = 0.0f;
30 }
31 }
32 return determinant;
33}
static bool SkIsFinite(T x, Pack... values)
static constexpr double sk_ieee_double_divide(double numer, double denom)

◆ SkInvert3x3Matrix()

SkScalar SkInvert3x3Matrix ( const SkScalar  inMatrix[9],
SkScalar  outMatrix[9] 
)

Definition at line 35 of file SkMatrixInvert.cpp.

35 {
36 double a00 = inMatrix[0];
37 double a01 = inMatrix[1];
38 double a02 = inMatrix[2];
39 double a10 = inMatrix[3];
40 double a11 = inMatrix[4];
41 double a12 = inMatrix[5];
42 double a20 = inMatrix[6];
43 double a21 = inMatrix[7];
44 double a22 = inMatrix[8];
45
46 double b01 = a22 * a11 - a12 * a21;
47 double b11 = -a22 * a10 + a12 * a20;
48 double b21 = a21 * a10 - a11 * a20;
49
50 // Calculate the determinant
51 double determinant = a00 * b01 + a01 * b11 + a02 * b21;
52 if (outMatrix) {
53 double invdet = sk_ieee_double_divide(1.0, determinant);
54 outMatrix[0] = b01 * invdet;
55 outMatrix[1] = (-a22 * a01 + a02 * a21) * invdet;
56 outMatrix[2] = ( a12 * a01 - a02 * a11) * invdet;
57 outMatrix[3] = b11 * invdet;
58 outMatrix[4] = ( a22 * a00 - a02 * a20) * invdet;
59 outMatrix[5] = (-a12 * a00 + a02 * a10) * invdet;
60 outMatrix[6] = b21 * invdet;
61 outMatrix[7] = (-a21 * a00 + a01 * a20) * invdet;
62 outMatrix[8] = ( a11 * a00 - a01 * a10) * invdet;
63 // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
64 // values is non-finite, return zero to indicate a non-invertible matrix.
65 if (!SkIsFinite(outMatrix, 9)) {
66 determinant = 0.0f;
67 }
68 }
69 return determinant;
70}

◆ SkInvert4x4Matrix()

SkScalar SkInvert4x4Matrix ( const SkScalar  inMatrix[16],
SkScalar  outMatrix[16] 
)

Definition at line 72 of file SkMatrixInvert.cpp.

72 {
73 double a00 = inMatrix[0];
74 double a01 = inMatrix[1];
75 double a02 = inMatrix[2];
76 double a03 = inMatrix[3];
77 double a10 = inMatrix[4];
78 double a11 = inMatrix[5];
79 double a12 = inMatrix[6];
80 double a13 = inMatrix[7];
81 double a20 = inMatrix[8];
82 double a21 = inMatrix[9];
83 double a22 = inMatrix[10];
84 double a23 = inMatrix[11];
85 double a30 = inMatrix[12];
86 double a31 = inMatrix[13];
87 double a32 = inMatrix[14];
88 double a33 = inMatrix[15];
89
90 double b00 = a00 * a11 - a01 * a10;
91 double b01 = a00 * a12 - a02 * a10;
92 double b02 = a00 * a13 - a03 * a10;
93 double b03 = a01 * a12 - a02 * a11;
94 double b04 = a01 * a13 - a03 * a11;
95 double b05 = a02 * a13 - a03 * a12;
96 double b06 = a20 * a31 - a21 * a30;
97 double b07 = a20 * a32 - a22 * a30;
98 double b08 = a20 * a33 - a23 * a30;
99 double b09 = a21 * a32 - a22 * a31;
100 double b10 = a21 * a33 - a23 * a31;
101 double b11 = a22 * a33 - a23 * a32;
102
103 // Calculate the determinant
104 double determinant = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
105 if (outMatrix) {
106 double invdet = sk_ieee_double_divide(1.0, determinant);
107 b00 *= invdet;
108 b01 *= invdet;
109 b02 *= invdet;
110 b03 *= invdet;
111 b04 *= invdet;
112 b05 *= invdet;
113 b06 *= invdet;
114 b07 *= invdet;
115 b08 *= invdet;
116 b09 *= invdet;
117 b10 *= invdet;
118 b11 *= invdet;
119
120 outMatrix[0] = a11 * b11 - a12 * b10 + a13 * b09;
121 outMatrix[1] = a02 * b10 - a01 * b11 - a03 * b09;
122 outMatrix[2] = a31 * b05 - a32 * b04 + a33 * b03;
123 outMatrix[3] = a22 * b04 - a21 * b05 - a23 * b03;
124 outMatrix[4] = a12 * b08 - a10 * b11 - a13 * b07;
125 outMatrix[5] = a00 * b11 - a02 * b08 + a03 * b07;
126 outMatrix[6] = a32 * b02 - a30 * b05 - a33 * b01;
127 outMatrix[7] = a20 * b05 - a22 * b02 + a23 * b01;
128 outMatrix[8] = a10 * b10 - a11 * b08 + a13 * b06;
129 outMatrix[9] = a01 * b08 - a00 * b10 - a03 * b06;
130 outMatrix[10] = a30 * b04 - a31 * b02 + a33 * b00;
131 outMatrix[11] = a21 * b02 - a20 * b04 - a23 * b00;
132 outMatrix[12] = a11 * b07 - a10 * b09 - a12 * b06;
133 outMatrix[13] = a00 * b09 - a01 * b07 + a02 * b06;
134 outMatrix[14] = a31 * b01 - a30 * b03 - a32 * b00;
135 outMatrix[15] = a20 * b03 - a21 * b01 + a22 * b00;
136
137 // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
138 // values is non-finite, return zero to indicate a non-invertible matrix.
139 if (!SkIsFinite(outMatrix, 16)) {
140 determinant = 0.0f;
141 }
142 }
143 return determinant;
144}