Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAlgebra2D::DecomposedMatrix Struct Reference

#include <kis_algebra_2d.h>

Public Member Functions

 DecomposedMatrix ()
 
 DecomposedMatrix (const QTransform &t0)
 
bool isValid () const
 
QTransform projectTransform () const
 
QTransform rotateTransform () const
 
QTransform scaleTransform () const
 
QTransform shearTransform () const
 
QTransform transform () const
 
QTransform translateTransform () const
 

Public Attributes

qreal angle = 0.0
 
qreal dx = 0.0
 
qreal dy = 0.0
 
qreal proj [3] = {0.0, 0.0, 1.0}
 
qreal scaleX = 1.0
 
qreal scaleY = 1.0
 
qreal shearXY = 0.0
 

Private Attributes

bool valid = true
 

Detailed Description

Definition at line 707 of file kis_algebra_2d.h.

Constructor & Destructor Documentation

◆ DecomposedMatrix() [1/2]

KisAlgebra2D::DecomposedMatrix::DecomposedMatrix ( )

Definition at line 790 of file kis_algebra_2d.cpp.

791{
792}

◆ DecomposedMatrix() [2/2]

KisAlgebra2D::DecomposedMatrix::DecomposedMatrix ( const QTransform & t0)

Definition at line 794 of file kis_algebra_2d.cpp.

795{
796 QTransform t(t0);
797
798 QTransform projMatrix;
799
800 if (t.m33() == 0.0 || t0.determinant() == 0.0) {
801 qWarning() << "Cannot decompose matrix!" << t;
802 valid = false;
803 return;
804 }
805
806 if (t.type() == QTransform::TxProject) {
807 QTransform affineTransform(
808 t.m11(), t.m12(), 0,
809 t.m21(), t.m22(), 0,
810 t.m31(), t.m32(), 1
811 );
812 projMatrix = affineTransform.inverted() * t;
813
814 t = affineTransform;
815 proj[0] = projMatrix.m13();
816 proj[1] = projMatrix.m23();
817 proj[2] = projMatrix.m33();
818 }
819
820 // can't use QVector3D, because they have too little accuracy for ellipse in perspective calculations
821 std::array<Eigen::Vector3d, 3> rows;
822
823
824 // << t.m11() << t.m12() << t.m13())
825 rows[0] = Eigen::Vector3d(t.m11(), t.m12(), t.m13());
826 rows[1] = Eigen::Vector3d(t.m21(), t.m22(), t.m23());
827 rows[2] = Eigen::Vector3d(t.m31(), t.m32(), t.m33());
828
829 if (!qFuzzyCompare(t.m33(), 1.0)) {
830 const qreal invM33 = 1.0 / t.m33();
831
832 for (auto &row : rows) {
833 row *= invM33;
834 }
835 }
836
837 dx = rows[2].x();
838 dy = rows[2].y();
839
840 rows[2] = Eigen::Vector3d(0,0,1);
841
842
843 scaleX = rows[0].norm();
844 rows[0] *= 1.0 / scaleX;
845
846 shearXY = rows[0].dot(rows[1]);
847 rows[1] = rows[1] - shearXY * rows[0];
848
849 scaleY = rows[1].norm();
850 rows[1] *= 1.0 / scaleY;
851 shearXY *= 1.0 / scaleY;
852
853 // If determinant is negative, one axis was flipped.
854 qreal determinant = rows[0].x() * rows[1].y() - rows[0].y() * rows[1].x();
855 if (determinant < 0) {
856 // Flip axis with minimum unit vector dot product.
857 if (rows[0].x() < rows[1].y()) {
858 scaleX = -scaleX;
859 rows[0] = -rows[0];
860 } else {
861 scaleY = -scaleY;
862 rows[1] = -rows[1];
863 }
864 shearXY = - shearXY;
865 }
866
867 angle = kisRadiansToDegrees(std::atan2(rows[0].y(), rows[0].x()));
868
869 if (angle != 0.0) {
870 // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)]
871 // = [row0x, -row0y, row0y, row0x]
872 // Thanks to the normalization above.
873
874 qreal sn = -rows[0].y();
875 qreal cs = rows[0].x();
876 qreal m11 = rows[0].x();
877 qreal m12 = rows[0].y();
878 qreal m21 = rows[1].x();
879 qreal m22 = rows[1].y();
880 rows[0][0] = (cs * m11 + sn * m21);
881 rows[0][1] = (cs * m12 + sn * m22);
882 rows[1][0] = (-sn * m11 + cs * m21);
883 rows[1][1] = (-sn * m12 + cs * m22);
884 }
885
886 QTransform leftOver(
887 rows[0].x(), rows[0].y(), rows[0].z(),
888 rows[1].x(), rows[1].y(), rows[1].z(),
889 rows[2].x(), rows[2].y(), rows[2].z());
890
891 if (/*true || */!fuzzyMatrixCompare(leftOver, QTransform(), 1e-4)) {
892 // what's wrong?
893 ENTER_FUNCTION() << "FAILING THE ASSERT BELOW!";
894 ENTER_FUNCTION() << ppVar(leftOver);
895 ENTER_FUNCTION() << "matrix to decompose was: " << ppVar(t0);
896 ENTER_FUNCTION() << ppVar(t.m33()) << ppVar(t0.determinant());
897 Eigen::Matrix3d mat1 = fromQTransformStraight(QTransform());
898 Eigen::Matrix3d mat2 = fromQTransformStraight(leftOver);
899 Eigen::Matrix3d mat3 = mat2 - mat1;
900 ENTER_FUNCTION() << mat3(0, 0) << mat3(0, 1) << mat3(0, 2);
901 ENTER_FUNCTION() << mat3(1, 0) << mat3(1, 1) << mat3(1, 2);
902 ENTER_FUNCTION() << mat3(2, 0) << mat3(2, 1) << mat3(2, 2);
903 //ENTER_FUNCTION() << ppVar(mat1 - mat2);
904 }
905
906
907 KIS_SAFE_ASSERT_RECOVER_NOOP(fuzzyMatrixCompare(leftOver, QTransform(), 1e-4));
908 KIS_ASSERT(fuzzyMatrixCompare(leftOver, QTransform(), 1e-4));
909}
static bool qFuzzyCompare(half p1, half p2)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define ENTER_FUNCTION()
Definition kis_debug.h:178
#define ppVar(var)
Definition kis_debug.h:155
T kisRadiansToDegrees(T radians)
Definition kis_global.h:181
bool fuzzyMatrixCompare(const QTransform &t1, const QTransform &t2, qreal delta)
Eigen::Matrix3d fromQTransformStraight(const QTransform &t)

References angle, dx, dy, ENTER_FUNCTION, KisAlgebra2D::fromQTransformStraight(), KisAlgebra2D::fuzzyMatrixCompare(), KIS_ASSERT, KIS_SAFE_ASSERT_RECOVER_NOOP, kisRadiansToDegrees(), ppVar, proj, qFuzzyCompare(), scaleX, scaleY, shearXY, and valid.

Member Function Documentation

◆ isValid()

bool KisAlgebra2D::DecomposedMatrix::isValid ( ) const
inline

Definition at line 754 of file kis_algebra_2d.h.

754 {
755 return valid;
756 }

◆ projectTransform()

QTransform KisAlgebra2D::DecomposedMatrix::projectTransform ( ) const
inline

Definition at line 736 of file kis_algebra_2d.h.

737 {
738 return
739 QTransform(
740 1,0,proj[0],
741 0,1,proj[1],
742 0,0,proj[2]);
743 }

◆ rotateTransform()

QTransform KisAlgebra2D::DecomposedMatrix::rotateTransform ( ) const
inline

Definition at line 724 of file kis_algebra_2d.h.

725 {
726 QTransform t;
727 t.rotate(angle);
728 return t;
729 }

◆ scaleTransform()

QTransform KisAlgebra2D::DecomposedMatrix::scaleTransform ( ) const
inline

Definition at line 712 of file kis_algebra_2d.h.

713 {
714 return QTransform::fromScale(scaleX, scaleY);
715 }

◆ shearTransform()

QTransform KisAlgebra2D::DecomposedMatrix::shearTransform ( ) const
inline

Definition at line 717 of file kis_algebra_2d.h.

718 {
719 QTransform t;
720 t.shear(shearXY, 0);
721 return t;
722 }

◆ transform()

QTransform KisAlgebra2D::DecomposedMatrix::transform ( ) const
inline

Definition at line 745 of file kis_algebra_2d.h.

745 {
746 return
752 }
QTransform shearTransform() const
QTransform projectTransform() const
QTransform rotateTransform() const
QTransform scaleTransform() const
QTransform translateTransform() const

◆ translateTransform()

QTransform KisAlgebra2D::DecomposedMatrix::translateTransform ( ) const
inline

Definition at line 731 of file kis_algebra_2d.h.

732 {
733 return QTransform::fromTranslate(dx, dy);
734 }

Member Data Documentation

◆ angle

qreal KisAlgebra2D::DecomposedMatrix::angle = 0.0

Definition at line 761 of file kis_algebra_2d.h.

◆ dx

qreal KisAlgebra2D::DecomposedMatrix::dx = 0.0

Definition at line 762 of file kis_algebra_2d.h.

◆ dy

qreal KisAlgebra2D::DecomposedMatrix::dy = 0.0

Definition at line 763 of file kis_algebra_2d.h.

◆ proj

qreal KisAlgebra2D::DecomposedMatrix::proj[3] = {0.0, 0.0, 1.0}

Definition at line 764 of file kis_algebra_2d.h.

764{0.0, 0.0, 1.0};

◆ scaleX

qreal KisAlgebra2D::DecomposedMatrix::scaleX = 1.0

Definition at line 758 of file kis_algebra_2d.h.

◆ scaleY

qreal KisAlgebra2D::DecomposedMatrix::scaleY = 1.0

Definition at line 759 of file kis_algebra_2d.h.

◆ shearXY

qreal KisAlgebra2D::DecomposedMatrix::shearXY = 0.0

Definition at line 760 of file kis_algebra_2d.h.

◆ valid

bool KisAlgebra2D::DecomposedMatrix::valid = true
private

Definition at line 767 of file kis_algebra_2d.h.


The documentation for this struct was generated from the following files: