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 920 of file kis_algebra_2d.h.

Constructor & Destructor Documentation

◆ DecomposedMatrix() [1/2]

KisAlgebra2D::DecomposedMatrix::DecomposedMatrix ( )

Definition at line 791 of file kis_algebra_2d.cpp.

792{
793}

◆ DecomposedMatrix() [2/2]

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

Definition at line 795 of file kis_algebra_2d.cpp.

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

967 {
968 return valid;
969 }

◆ projectTransform()

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

Definition at line 949 of file kis_algebra_2d.h.

950 {
951 return
952 QTransform(
953 1,0,proj[0],
954 0,1,proj[1],
955 0,0,proj[2]);
956 }

◆ rotateTransform()

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

Definition at line 937 of file kis_algebra_2d.h.

938 {
939 QTransform t;
940 t.rotate(angle);
941 return t;
942 }

◆ scaleTransform()

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

Definition at line 925 of file kis_algebra_2d.h.

926 {
927 return QTransform::fromScale(scaleX, scaleY);
928 }

◆ shearTransform()

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

Definition at line 930 of file kis_algebra_2d.h.

931 {
932 QTransform t;
933 t.shear(shearXY, 0);
934 return t;
935 }

◆ transform()

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

Definition at line 958 of file kis_algebra_2d.h.

958 {
959 return
965 }
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 944 of file kis_algebra_2d.h.

945 {
946 return QTransform::fromTranslate(dx, dy);
947 }

Member Data Documentation

◆ angle

qreal KisAlgebra2D::DecomposedMatrix::angle = 0.0

Definition at line 974 of file kis_algebra_2d.h.

◆ dx

qreal KisAlgebra2D::DecomposedMatrix::dx = 0.0

Definition at line 975 of file kis_algebra_2d.h.

◆ dy

qreal KisAlgebra2D::DecomposedMatrix::dy = 0.0

Definition at line 976 of file kis_algebra_2d.h.

◆ proj

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

Definition at line 977 of file kis_algebra_2d.h.

977{0.0, 0.0, 1.0};

◆ scaleX

qreal KisAlgebra2D::DecomposedMatrix::scaleX = 1.0

Definition at line 971 of file kis_algebra_2d.h.

◆ scaleY

qreal KisAlgebra2D::DecomposedMatrix::scaleY = 1.0

Definition at line 972 of file kis_algebra_2d.h.

◆ shearXY

qreal KisAlgebra2D::DecomposedMatrix::shearXY = 0.0

Definition at line 973 of file kis_algebra_2d.h.

◆ valid

bool KisAlgebra2D::DecomposedMatrix::valid = true
private

Definition at line 980 of file kis_algebra_2d.h.


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