From 34a6856a6784c0f0959c64c173e0edf55fb15d7f Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Feb 23 2020 13:14:56 +0000 Subject: improve synfig::Matrix --- diff --git a/synfig-core/src/synfig/matrix.cpp b/synfig-core/src/synfig/matrix.cpp index 5f6c5d0..a26751c 100644 --- a/synfig-core/src/synfig/matrix.cpp +++ b/synfig-core/src/synfig/matrix.cpp @@ -111,29 +111,28 @@ Matrix2::operator+=(const Matrix2 &rhs) return *this; } +Matrix2::value_type +Matrix2::det() const + { return m00*m11 - m01*m10; } + bool -Matrix2::is_invertible()const - { return approximate_not_equal(m00*m11, m01*m10); } +Matrix2::is_invertible() const + { return approximate_not_zero(det()); } Matrix2& Matrix2::invert() { - value_type det(m00*m11 - m01*m10); - if (approximate_not_equal(det, 0.0)) - { - value_type k = 1.0/det; + value_type d = det(); + if (approximate_not_zero(d)) { + value_type k = 1/d; std::swap(m00, m11); std::swap(m01, m10); m00 *= k; m01 *= -k; m11 *= k; m10 *= -k; - } - else - if (m00*m00 + m01*m01 > m10*m10 + m11*m11) - { + } else + if (m00*m00 + m01*m01 > m10*m10 + m11*m11) { m10 = m01; m01 = 0; m11 = 0; - } - else - { + } else { m01 = m10; m00 = 0; m10 = 0; } return *this; @@ -321,6 +320,21 @@ Matrix3::get_inverted()const p*(m00*m11 - m01*m10) ); } +Matrix3& +Matrix3::normalize_by_z() +{ + Real k = m02*m02 + m12*m12 + m22*m22; + if (k > real_precision()*real_precision()) { + k = 1/sqrt(k); + if (m22 < 0) k = -k; + for(int i = 0; i < 3; ++i) + for(int j = 0; j < 3; ++j) + m[i][j] *= k; + } + return *this; +} + + String Matrix3::get_string(int spaces, String before, String after)const { diff --git a/synfig-core/src/synfig/matrix.h b/synfig-core/src/synfig/matrix.h index 66d5f77..e051cbf 100644 --- a/synfig-core/src/synfig/matrix.h +++ b/synfig-core/src/synfig/matrix.h @@ -98,6 +98,9 @@ public: bool is_identity() const { return *this == Matrix2(); } + Matrix2& set_zero() + { return *this = Matrix2(Vector(), Vector()); } + //!set_scale member function. Sets a scale matrix //! @param sx Scale by X axis //! @param sy Scale by Y axis @@ -171,6 +174,8 @@ public: Matrix2 operator+(const Matrix2 &rhs)const { return Matrix2(*this) += rhs; } + value_type det() const; + bool is_invertible()const; Matrix2& invert(); @@ -274,6 +279,9 @@ public: bool is_identity() const { return *this == Matrix3(); } + Matrix3& set_zero() + { return *this = Matrix3(Vector3(), Vector3(), Vector3()); } + //!set_scale member function. Sets a scale matrix //! @param sx Scale by X axis //! @param sy Scale by Y axis @@ -373,7 +381,15 @@ public: Matrix3& invert() { return *this = get_inverted(); } - + + Matrix3 get_normalized_by_z() const + { return Matrix3(*this).normalize_by_z(); } + + Matrix3& normalize_by_z(); + + Matrix2 to_2d() const + { return Matrix2(m00, m01, m10, m11); } + //!Get the string of the Matrix //!@return String type. A string representation of the matrix //!components. diff --git a/synfig-core/src/synfig/rect.h b/synfig-core/src/synfig/rect.h index 1f6d372..eb30294 100644 --- a/synfig-core/src/synfig/rect.h +++ b/synfig-core/src/synfig/rect.h @@ -265,7 +265,7 @@ public: value_type get_width()const { return maxx - minx; } value_type get_height()const { return maxy - miny; } - bool is_inside(const Point& x) + bool is_inside(const Point& x) const { return approximate_less_or_equal(minx, x[0]) && approximate_less_or_equal(x[0], maxx) diff --git a/synfig-core/src/synfig/vector.h b/synfig-core/src/synfig/vector.h index 70e2046..37acdaa 100644 --- a/synfig-core/src/synfig/vector.h +++ b/synfig-core/src/synfig/vector.h @@ -451,8 +451,10 @@ public: { return Vector3(_x/rhs._x, _y/rhs._y, _z/rhs._z); } Vector3 one_divide_coords() const { return Vector3(1.0/_x, 1.0/_y, 1.0/_z); } - Vector3 divide_z() const - { value_type tmp = 1.0/_z; return Vector3(_x*tmp, _y*tmp, 1.0); } + Vector3 divide_z() const { + if (approximate_zero(_z)) return Vector3(); + value_type tmp = 1.0/_z; return Vector3(_x*tmp, _y*tmp, 1.0); + } Vector to_2d() const { return Vector(_x, _y); } };