Blob Blame Raw

#include "matrix.h"


Matrix
Matrix::get_inverted() const {
	Real d = det();
	if (equal(d, 0)) {
		// try to make back transform for X-axis
		if (equal(m02, 0) && equal(m10, 0) && equal(m11, 0) && equal(m12, 0) && equal(m22, 1)) {
			d = axis_x().lensqr();
			if (d > precision) {
				d = 1.0/d;
				return Matrix(
				    d*m00,                 0, 0,
				    d*m01,                 0, 0,
				   -d*(m20*m00 + m21*m01), 0, 1 );
			}
		}

		// try to make back transform for Y-axis
		if (equal(m00, 0) && equal(m01, 0) && equal(m02, 0) && equal(m12, 0) && equal(m22, 1)) {
			d = axis_y().lensqr();
			if (d > precision) {
				d = 1/d;
				return Matrix(
				    0,  d*m10,                 0,
					0,  d*m11,                 0,
					0, -d*(m20*m10 + m21*m11), 1 );
			}
		}

		// give up
		return Matrix( 0, 0, 0,
					   0, 0, 0,
					   0, 0, 0 );
	}

	// proper inversion
	Real p = 1/d, m = -p;
	return Matrix(
		p*(m11*m22 - m12*m21), // row0
		m*(m01*m22 - m02*m21),
		p*(m01*m12 - m02*m11),
		m*(m10*m22 - m12*m20), // row1
		p*(m00*m22 - m02*m20),
		m*(m00*m12 - m02*m10),
		p*(m10*m21 - m11*m20), // row2
		m*(m00*m21 - m01*m20),
		p*(m00*m11 - m01*m10) );
}