21#include "kis_perspective_math.h"
32#define DEFAULT_ALLOC 2
36template <
class ElType>
class matrix;
38template <
class ElType>
42 friend class matrix<ElType>;
48 ~vector(){
delete [] data;}
50 vector(
const vector<ElType>& v) ;
52 vector<ElType>& operator =(
const vector<ElType> &original);
53 ElType& operator[](
int i)
const ;
55 vector<ElType> operator+(
const vector<ElType>& v);
56 vector<ElType> operator-(
const vector<ElType>&v);
59 int operator==(
const vector<ElType>& v)
const;
60 friend vector<ElType> operator* (ElType c,vector<ElType>& v );
61 friend vector<ElType> operator*(vector<ElType>& v,ElType c );
62 friend std::ostream& operator<<(std::ostream& s,vector<ElType>& v);
64template <
class ElType>
65 void vector<ElType>::zero()
67 for(
int i=0;i<len;i++) data[i]=(ElType)0;
69template <
class ElType>
70 int vector<ElType>::length()
const
74template <
class ElType>
75 ElType& vector<ElType>::operator[](
int i)
const
77 assert(i>=0 && i < len);
81template <
class ElType>
82 vector<ElType>::vector()
84 data=
new ElType[ DEFAULT_ALLOC];
88template <
class ElType>
89 vector<ElType>::vector(
int n)
91 data =
new ElType[len=n];
94template <
class ElType>
95 vector<ElType>::vector(
const vector<ElType>& v)
97 data=
new ElType[len=v.len];
99 for(
int i=0;i<len;i++) data[i]=v.data[i];
101template <
class ElType>
102 vector<ElType>& vector<ElType>::operator =(
const vector<ElType> &original)
104 if(
this != &original)
107 data=
new ElType[len=original.len];
109 for(
int i=0;i<len;i++) data[i]=original.data[i];
113template <
class ElType>
114 vector<ElType> vector<ElType>::operator+(
const vector<ElType>& v)
116 vector<ElType> sum(len);
117 for(
int i=0;i<len;i++) sum[i] = data[i]+v.data[i];
121template <
class ElType>
122 vector<ElType> vector<ElType>::operator-(
const vector<ElType>& v)
124 vector<ElType> sum(len);
125 for(
int i=0;i<len;i++) sum[i] = data[i]-v.data[i];
128template <
class ElType>
129 void vector<ElType>::rprint()const
132 std::cout <<
"VECTOR: ";
134 for(i=0;i<len-1;i++) std::cout << data[i] <<
",";
135 std::cout << data[len-1] <<
")" << std::endl;
138template <
class ElType>
139 void vector<ElType>::resize(
int n)
142 data =
new ElType[len=n];
145template <
class ElType>
146 int vector<ElType>::operator==(
const vector<ElType>& v)
const
148 if(len != v.len)
return 0;
149 for(
int i=0;i<len;i++)
if(data[i]!=v.data[i])
return 0;
152template <
class ElType>
153 vector<ElType> operator*(ElType c,vector<ElType>& v )
155 vector<ElType> ans(v.len);
156 for(
int i=0;i<v.len;i++) ans[i]=c*v[i];
159template <
class ElType>
160 vector<ElType> operator*(vector<ElType>& v,ElType c )
162 vector<ElType> ans(v.len);
163 for(
int i=0;i<v.len;i++) ans[i]=c*v[i];
166template <
class ElType>
167 std::ostream& operator<<(std::ostream& s,vector<ElType>& v)
170 for(
int i=0;i<v.len-1;i++) s << v.data[i] <<
", ";
171 s << v.data[v.len-1]<<
")"<<endl;
175template <
class ElType>
182 matrix(
int r,
int c);
183 matrix(
const matrix<ElType> &s);
185 matrix& operator =(
const matrix<ElType>& s);
186 vector<ElType>& operator[](
const int i);
187 vector<ElType> operator*(
const vector<ElType>&);
188 friend matrix<ElType> operator*(
const ElType&,
const matrix<ElType>&);
189 friend matrix<ElType> operator*(
const matrix<ElType>&,
const ElType&);
190 matrix<ElType> operator*(
const matrix<ElType>& a);
191 matrix<ElType> operator+(
const matrix<ElType>& a);
192 matrix<ElType> operator-(
const matrix<ElType>& a);
193 matrix<ElType> transpose();
195 friend std::ostream& operator<<(std::ostream& s,matrix<ElType>& m);
196 friend void ludcmp(matrix<ElType>& a,vector<int>& indx,
double &d);
197 friend void lubksb(matrix<ElType>&a,vector<int>& indx,vector<ElType>&b);
199template <
class ElType>
200 matrix<ElType>::matrix()
202 m =
new vector<ElType>[DEFAULT_ALLOC];
204 rows=cols=DEFAULT_ALLOC;
205 for(
int i=0;i<rows;i++)
212template <
class ElType>
213 matrix<ElType>::matrix(
int r,
int c)
215 m=
new vector<ElType>[r];
221 vector<ElType> v(cols);
225template <
class ElType>
226 matrix<ElType>::matrix(
const matrix<ElType> &s)
230 m =
new vector<ElType>[rows];
238template <
class ElType>
239 matrix<ElType>::~matrix()
244template <
class ElType>
245 matrix<ElType>& matrix<ElType>::operator =(
const matrix<ElType> &s)
252 m =
new vector<ElType>[rows];
254 for(
int i=0;i<rows;i++) m[i]=s.m[i];
258template <
class ElType>
259 vector<ElType>& matrix<ElType>::operator[](
const int i)
261 assert(i>=0 && i < rows);
264template <
class ElType>
265 vector<ElType> matrix<ElType>::operator*(
const vector<ElType>& v)
268 assert(cols == v.len);
269 vector<ElType> ans(rows);
273 for(j=0;j<cols;j++) ans.data[i] += m[i][j]*v.data[j];
277template <
class ElType>
278 matrix<ElType> operator*(
const ElType& x,
const matrix<ElType>& s)
280 matrix<ElType> ans(s.rows,s.cols);
281 for(
int i=0;i<ans.rows;i++)
287template <
class ElType>
288 matrix<ElType> matrix<ElType>::transpose()
290 matrix<ElType> ans(cols,rows);
291 for(
int i=0;i<rows;i++)
293 for(
int j=0;j<cols;j++) ans[j][i]=m[i][j];
297template <
class ElType>
298 matrix<ElType> operator*(
const matrix<ElType>& s,
const ElType& x)
300 matrix<ElType> ans(s.rows,s.cols);
301 for(
int i=0;i<ans.rows;i++)
307template <
class ElType>
308 matrix<ElType> matrix<ElType> ::operator*(
const matrix<ElType>& a)
311 assert(cols == a.rows);
313 matrix<ElType> ans(rows,a.cols);
314 for(
int i=0;i<rows;i++)
316 for(
int j=0;j<a.cols;j++)
319 for(
int k=0;k<cols;k++)
321 ans.m[i][j] += m[i][k]*a.m[k][j];
327template <
class ElType>
328 matrix<ElType> matrix<ElType> ::operator+(
const matrix<ElType> & a)
332 assert(rows== a.rows);
333 assert(cols== a.cols);
335 matrix<ElType> ans(a.rows,a.cols);
336 for(i=0;i<a.rows;i++)
338 for(j=0;j<a.cols;j++)
340 ans.m[i][j] = m[i][j] + a.m[i][j];
345template <
class ElType>
346 matrix<ElType> matrix<ElType>::operator-(
const matrix<ElType>& a)
349 assert(rows == a.rows);
350 assert(cols == a.cols);
351 matrix ans(rows,cols);
355 ans.m[i][j] = m[i][j] - a.m[i][j];
359template <
class ElType>
360 std::ostream& operator<<(std::ostream& s,matrix<ElType>& m)
362 for(
int i=0; i<m.rows;i++) s << m[i];
369template <
class ElType>
370void ludcmp(matrix<ElType>& a, vector<int>& indx,
double& d)
373 ElType big,dum,sum,temp;
375 vector<ElType> vv(n);
376 assert(a.rows == a.cols);
382 for (j=0;j<n;j++) {
if ((temp=fabs(a[i][j])) > big) big=temp;
384 if (big == 0.0) { std::cerr <<
"Singular matrix in routine LUDCMP" << std::endl; big = TINY;}
392 for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
399 for (k=0;k<j;k++) sum -= a[i][k]*a[k][j];
401 if ( (dum=vv[i]*fabs(sum)) >= big)
419 if (a[j][j] == 0.0) a[j][j]=TINY;
422 for (i=j+1;i<n;i++) a[i][j] *= dum;
427template <
class ElType>
428void lubksb(matrix<ElType>& a,vector<int>& indx,vector<ElType>& b)
438 for (j=0;j<=i-1;j++) sum -= a[i][j]*b[j];
444 for (j=i+1;j<n;j++) sum -= a[i][j]*b[j];
456 double* matrix =
new double[9];
458 math::matrix<double> a(10,10);
459 math::vector<double> b(10);
460 math::vector<int> indx(10);
462 for(
int i = 0; i <= 9; i++)
464 for(
int j = 0; j <= 9; j++)
473 a[0][0] = topLeft1.x();
474 a[0][1] = topLeft1.y();
476 a[0][6] = -topLeft2.x() * topLeft1.x();
477 a[0][7] = -topLeft2.x() * topLeft1.y();
478 a[0][8] = -topLeft2.x();
479 a[1][3] = topLeft1.x();
480 a[1][4] = topLeft1.y();
482 a[1][6] = -topLeft2.y() * topLeft1.x();
483 a[1][7] = -topLeft2.y() * topLeft1.y();
484 a[1][8] = -topLeft2.y();
486 a[2][0] = topRight1.x();
487 a[2][1] = topRight1.y();
489 a[2][6] = -topRight2.x() * topRight1.x();
490 a[2][7] = -topRight2.x() * topRight1.y();
491 a[2][8] = -topRight2.x();
492 a[3][3] = topRight1.x();
493 a[3][4] = topRight1.y();
495 a[3][6] = -topRight2.y() * topRight1.x();
496 a[3][7] = -topRight2.y() * topRight1.y();
497 a[3][8] = -topRight2.y();
499 a[4][0] = bottomLeft1.x();
500 a[4][1] = bottomLeft1.y();
502 a[4][6] = -bottomLeft2.x() * bottomLeft1.x();
503 a[4][7] = -bottomLeft2.x() * bottomLeft1.y();
504 a[4][8] = -bottomLeft2.x();
505 a[5][3] = bottomLeft1.x();
506 a[5][4] = bottomLeft1.y();
508 a[5][6] = -bottomLeft2.y() * bottomLeft1.x();
509 a[5][7] = -bottomLeft2.y() * bottomLeft1.y();
510 a[5][8] = -bottomLeft2.y();
512 a[6][0] = bottomRight1.x();
513 a[6][1] = bottomRight1.y();
515 a[6][6] = -bottomRight2.x() * bottomRight1.x();
516 a[6][7] = -bottomRight2.x() * bottomRight1.y();
517 a[6][8] = -bottomRight2.x();
518 a[7][3] = bottomRight1.x();
519 a[7][4] = bottomRight1.y();
521 a[7][6] = -bottomRight2.y() * bottomRight1.x();
522 a[7][7] = -bottomRight2.y() * bottomRight1.y();
523 a[7][8] = -bottomRight2.y();
527 math::ludcmp<double>(a,indx,d);
528 math::lubksb<double>(a,indx,b);
530 for(
int i = 0; i < 9; i++)
537double* KisPerspectiveMath::computeMatrixTransfoToPerspective(
const KisPoint& topLeft,
const KisPoint& topRight,
const KisPoint& bottomLeft,
const KisPoint& bottomRight,
const TQRect& r)
539 return KisPerspectiveMath::computeMatrixTransfo(topLeft, topRight, bottomLeft, bottomRight,
KisPoint(r.topLeft()),
KisPoint(r.topRight()),
KisPoint(r.bottomLeft()),
KisPoint(r.bottomRight()));
542double* KisPerspectiveMath::computeMatrixTransfoFromPerspective(
const TQRect& r,
const KisPoint& topLeft,
const KisPoint& topRight,
const KisPoint& bottomLeft,
const KisPoint& bottomRight)
544 return KisPerspectiveMath::computeMatrixTransfo(
KisPoint(r.topLeft()),
KisPoint(r.topRight()),
KisPoint(r.bottomLeft()),
KisPoint(r.bottomRight()), topLeft, topRight, bottomLeft, bottomRight);
A double-based point class that can return it's coordinates approximated to integers.