File indexing completed on 2025-01-19 03:51:13
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2005-02-17 0007 * Description : a matrix implementation for image 0008 * perspective adjustment. 0009 * 0010 * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2006-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0012 * 0013 * Based on PerspectiveMatrix3 implementation inspired from gimp 2.0 0014 * from Spencer Kimball and Peter Mattis. 0015 * 0016 * SPDX-License-Identifier: GPL-2.0-or-later 0017 * 0018 * ============================================================ */ 0019 0020 #include "perspectivematrix.h" 0021 0022 // C++ includes 0023 0024 #include <cstring> 0025 0026 namespace DigikamEditorPerspectiveToolPlugin 0027 { 0028 0029 static double identityPerspectiveMatrix[3][3] = 0030 { 0031 { 1.0, 0.0, 0.0 }, 0032 { 0.0, 1.0, 0.0 }, 0033 { 0.0, 0.0, 1.0 } 0034 }; 0035 0036 PerspectiveMatrix::PerspectiveMatrix() 0037 { 0038 memcpy(coeff, identityPerspectiveMatrix, sizeof(coeff)); 0039 } 0040 0041 void PerspectiveMatrix::translate (double x, double y) 0042 { 0043 double g, h, i; 0044 0045 g = coeff[2][0]; 0046 h = coeff[2][1]; 0047 i = coeff[2][2]; 0048 0049 coeff[0][0] += x * g; 0050 coeff[0][1] += x * h; 0051 coeff[0][2] += x * i; 0052 coeff[1][0] += y * g; 0053 coeff[1][1] += y * h; 0054 coeff[1][2] += y * i; 0055 } 0056 0057 void PerspectiveMatrix::scale(double x, double y) 0058 { 0059 coeff[0][0] *= x; 0060 coeff[0][1] *= x; 0061 coeff[0][2] *= x; 0062 0063 coeff[1][0] *= y; 0064 coeff[1][1] *= y; 0065 coeff[1][2] *= y; 0066 } 0067 0068 void PerspectiveMatrix::multiply(const PerspectiveMatrix& matrix) 0069 { 0070 PerspectiveMatrix tmp; 0071 double t1, t2, t3; 0072 0073 for (int i = 0; i < 3; ++i) 0074 { 0075 t1 = matrix.coeff[i][0]; 0076 t2 = matrix.coeff[i][1]; 0077 t3 = matrix.coeff[i][2]; 0078 0079 for (int j = 0; j < 3; ++j) 0080 { 0081 tmp.coeff[i][j] = t1 * coeff[0][j]; 0082 tmp.coeff[i][j] += t2 * coeff[1][j]; 0083 tmp.coeff[i][j] += t3 * coeff[2][j]; 0084 } 0085 } 0086 0087 *this = tmp; 0088 } 0089 0090 void PerspectiveMatrix::transformPoint(double x, double y, double* newx, double* newy) const 0091 { 0092 double w = coeff[2][0] * x + coeff[2][1] * y + coeff[2][2]; 0093 0094 if (w == 0.0) 0095 { 0096 w = 1.0; 0097 } 0098 else 0099 { 0100 w = 1.0/w; 0101 } 0102 0103 *newx = (coeff[0][0] * x + 0104 coeff[0][1] * y + 0105 coeff[0][2]) * w; 0106 *newy = (coeff[1][0] * x + 0107 coeff[1][1] * y + 0108 coeff[1][2]) * w; 0109 } 0110 0111 void PerspectiveMatrix::invert() 0112 { 0113 PerspectiveMatrix inv; 0114 double det = determinant(); 0115 0116 if (det == 0.0) 0117 { 0118 return; 0119 } 0120 0121 det = 1.0 / det; 0122 0123 inv.coeff[0][0] = (coeff[1][1] * coeff[2][2] - 0124 coeff[1][2] * coeff[2][1]) * det; 0125 0126 inv.coeff[1][0] = - (coeff[1][0] * coeff[2][2] - 0127 coeff[1][2] * coeff[2][0]) * det; 0128 0129 inv.coeff[2][0] = (coeff[1][0] * coeff[2][1] - 0130 coeff[1][1] * coeff[2][0]) * det; 0131 0132 inv.coeff[0][1] = - (coeff[0][1] * coeff[2][2] - 0133 coeff[0][2] * coeff[2][1]) * det; 0134 0135 inv.coeff[1][1] = (coeff[0][0] * coeff[2][2] - 0136 coeff[0][2] * coeff[2][0]) * det; 0137 0138 inv.coeff[2][1] = - (coeff[0][0] * coeff[2][1] - 0139 coeff[0][1] * coeff[2][0]) * det; 0140 0141 inv.coeff[0][2] = (coeff[0][1] * coeff[1][2] - 0142 coeff[0][2] * coeff[1][1]) * det; 0143 0144 inv.coeff[1][2] = - (coeff[0][0] * coeff[1][2] - 0145 coeff[0][2] * coeff[1][0]) * det; 0146 0147 inv.coeff[2][2] = (coeff[0][0] * coeff[1][1] - 0148 coeff[0][1] * coeff[1][0]) * det; 0149 0150 *this = inv; 0151 } 0152 0153 double PerspectiveMatrix::determinant() const 0154 { 0155 double determinant; 0156 0157 determinant = (coeff[0][0] * 0158 (coeff[1][1] * coeff[2][2] - 0159 coeff[1][2] * coeff[2][1])); 0160 determinant -= (coeff[1][0] * 0161 (coeff[0][1] * coeff[2][2] - 0162 coeff[0][2] * coeff[2][1])); 0163 determinant += (coeff[2][0] * 0164 (coeff[0][1] * coeff[1][2] - 0165 coeff[0][2] * coeff[1][1])); 0166 0167 return determinant; 0168 } 0169 0170 } // namespace DigikamEditorPerspectiveToolPlugin