Blame c++/vector/matrix.cpp

Ivan Mahonin 145120
Ivan Mahonin 145120
#include "matrix.h"
Ivan Mahonin 145120
Ivan Mahonin 145120
Ivan Mahonin 145120
Matrix
Ivan Mahonin 145120
Matrix::get_inverted() const {
Ivan Mahonin 145120
	Real d = det();
Ivan Mahonin 145120
	if (equal(d, 0)) {
Ivan Mahonin 145120
		// try to make back transform for X-axis
Ivan Mahonin 145120
		if (equal(m02, 0) && equal(m10, 0) && equal(m11, 0) && equal(m12, 0) && equal(m22, 1)) {
Ivan Mahonin 145120
			d = axis_x().lensqr();
Ivan Mahonin 145120
			if (d > precision) {
Ivan Mahonin 145120
				d = 1.0/d;
Ivan Mahonin 145120
				return Matrix(
Ivan Mahonin 145120
				    d*m00,                 0, 0,
Ivan Mahonin 145120
				    d*m01,                 0, 0,
Ivan Mahonin 145120
				   -d*(m20*m00 + m21*m01), 0, 1 );
Ivan Mahonin 145120
			}
Ivan Mahonin 145120
		}
Ivan Mahonin 145120
Ivan Mahonin 145120
		// try to make back transform for Y-axis
Ivan Mahonin 145120
		if (equal(m00, 0) && equal(m01, 0) && equal(m02, 0) && equal(m12, 0) && equal(m22, 1)) {
Ivan Mahonin 145120
			d = axis_y().lensqr();
Ivan Mahonin 145120
			if (d > precision) {
Ivan Mahonin 145120
				d = 1/d;
Ivan Mahonin 145120
				return Matrix(
Ivan Mahonin 145120
				    0,  d*m10,                 0,
Ivan Mahonin 145120
					0,  d*m11,                 0,
Ivan Mahonin 145120
					0, -d*(m20*m10 + m21*m11), 1 );
Ivan Mahonin 145120
			}
Ivan Mahonin 145120
		}
Ivan Mahonin 145120
Ivan Mahonin 145120
		// give up
Ivan Mahonin 145120
		return Matrix( 0, 0, 0,
Ivan Mahonin 145120
					   0, 0, 0,
Ivan Mahonin 145120
					   0, 0, 0 );
Ivan Mahonin 145120
	}
Ivan Mahonin 145120
Ivan Mahonin 145120
	// proper inversion
Ivan Mahonin 145120
	Real p = 1/d, m = -p;
Ivan Mahonin 145120
	return Matrix(
Ivan Mahonin 145120
		p*(m11*m22 - m12*m21), // row0
Ivan Mahonin 145120
		m*(m01*m22 - m02*m21),
Ivan Mahonin 145120
		p*(m01*m12 - m02*m11),
Ivan Mahonin 145120
		m*(m10*m22 - m12*m20), // row1
Ivan Mahonin 145120
		p*(m00*m22 - m02*m20),
Ivan Mahonin 145120
		m*(m00*m12 - m02*m10),
Ivan Mahonin 145120
		p*(m10*m21 - m11*m20), // row2
Ivan Mahonin 145120
		m*(m00*m21 - m01*m20),
Ivan Mahonin 145120
		p*(m00*m11 - m01*m10) );
Ivan Mahonin 145120
}