wxArt2D
afmatrix.cpp
Go to the documentation of this file.
1 /*! \file artbase/src/afmatrix.cpp
2  \brief a2dAffineMatrix class
3  \author Klaas Holwerda Chris Breeze, Julian Smart
4 
5  Copyright: 2001-2004 (C) Klaas Holwerda Chris Breeze, Julian Smart
6 
7  Licence: wxWidgets licence
8 
9  RCS-ID: $Id: afmatrix.cpp,v 1.42 2009/09/10 17:04:08 titato Exp $
10 */
11 
12 #include "a2dprec.h"
13 #include "wx/general/genmod.h"
14 
15 #if wxART2D_USE_CVGIO
16 #include "wx/xmlparse/genxmlpars.h"
17 #endif //wxART2D_USE_CVGIO
18 
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22 
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26 
27 #include "wx/artbase/afmatrix.h"
28 #include <math.h>
29 #include <ctype.h>
30 
31 #if defined(__VISUALC__)
32 
33 // MSVC warning 4660 is quite stupid. It says that the template is already instantiated
34 // by using it, but it is not fully instantiated as required for a library
35 #ifdef _MSC_VER
36 #pragma warning(disable: 4660)
37 #endif
38 
41 
42 #ifdef _MSC_VER
43 #pragma warning(default: 4660)
44 #endif
45 
46 #endif
47 
48 IMPLEMENT_DYNAMIC_CLASS( a2dMatrixProperty, a2dNamedProperty )
49 IMPLEMENT_DYNAMIC_CLASS( a2dPoint2DProperty, a2dNamedProperty )
50 
52 
53 a2dAffineMatrix::a2dAffineMatrix( double xt, double yt, double scalex, double scaley, double degrees )
54 {
55  if ( degrees )
56  {
57  double angle = wxDegToRad( -degrees );
58  double c = cos( angle );
59  double s = sin( angle );
60 
61  m_matrix[0][0] = c * scalex;
62  m_matrix[1][0] = -s * scaley;
63  m_matrix[2][0] = xt;
64  m_matrix[0][1] = s * scalex;
65  m_matrix[1][1] = c * scaley;
66  m_matrix[2][1] = yt;
67 
68  }
69  else
70  {
71  m_matrix[0][0] = scalex;
72  m_matrix[1][0] = 0;
73  m_matrix[2][0] = xt;
74  m_matrix[0][1] = 0;
75  m_matrix[1][1] = scaley;
76  m_matrix[2][1] = yt;
77  }
78 
79  m_isIdentity = IsIdentity1();
80 }
81 
82 a2dAffineMatrix::a2dAffineMatrix( double sx, double shx, double shy, double sy, double tx, double ty )
83 {
84  m_matrix[0][0] = sx;
85  m_matrix[1][0] = shy;
86  m_matrix[2][0] = tx;
87  m_matrix[0][1] = shx;
88  m_matrix[1][1] = sy;
89  m_matrix[2][1] = ty;
91 }
92 
94 {
95  Identity();
96 }
97 
99 {
100  memcpy( m_matrix, mat.m_matrix, 6 * sizeof( double ) );
102 
103  //(*this) = mat;
104 }
105 
106 double a2dAffineMatrix::GetValue( int col, int row ) const
107 {
108  if ( row < 0 || row > 1 || col < 0 || col > 2 )
109  return 0.0;
110 
111  return m_matrix[col][row];
112 }
113 
114 void a2dAffineMatrix::SetValue( int col, int row, double value )
115 {
116  if ( row < 0 || row > 1 || col < 0 || col > 2 )
117  return;
118 
119  m_matrix[col][row] = value;
121 }
122 
124 {
125  /*
126  int i, j;
127  for (i = 0; i < 3; i++)
128  {
129  for (j = 0; j < 2; j++)
130  {
131  m_matrix[i][j] = mat.m_matrix[i][j];
132  }
133  }
134  */
135  memcpy( m_matrix, mat.m_matrix, 6 * sizeof( double ) );
136 
138 }
139 
140 A2DARTBASEDLLEXP bool operator == ( const a2dAffineMatrix& a, const a2dAffineMatrix& b )
141 {
142  if ( a.m_isIdentity && b.m_isIdentity )
143  return true;
144 
145  if ( memcmp( a.m_matrix, b.m_matrix, sizeof( a.m_matrix ) ) )
146  return false;
147 
148  return true;
149 }
150 
151 A2DARTBASEDLLEXP bool operator != ( const a2dAffineMatrix& a, const a2dAffineMatrix& b )
152 {
153  return ( ! ( a == b ) );
154 }
155 
156 
158 {
159  if ( m_isIdentity && a.m_isIdentity )
160  return true;
161 
162  if ( memcmp( m_matrix, a.m_matrix, sizeof( m_matrix ) ) )
163  return false;
164 
165  return true;
166 }
167 
169 {
170  return ( ! ( *this == a ) );
171 }
172 
173 
174 double& a2dAffineMatrix::operator()( int col, int row )
175 {
176  if ( row < 0 || row > 1 || col < 0 || col > 2 )
177  return m_matrix[0][0];
178 
179  return m_matrix[col][row];
180 }
181 
182 double a2dAffineMatrix::operator()( int col, int row ) const
183 {
184  if ( row < 0 || row > 1 || col < 0 || col > 2 )
185  return 0.0;
186 
187  return m_matrix[col][row];
188 }
189 
190 //! Calculates the determinant of a 2 x 2 matrix
191 inline double wxCalculateDet( double a11, double a21, double a12, double a22 )
192 {
193  return a11 * a22 - a12 * a21;
194 }
195 
196 // Invert matrix
198 {
199  if ( m_isIdentity )
200  return true;
201 
202  double inverseMatrix[3][2];
203  double det = m_matrix[0][0] * m_matrix[1][1] - m_matrix[0][1] * m_matrix[1][0];
204 
205  if( det )
206  {
207  // calculate the adjoint
208  inverseMatrix[0][0] = m_matrix[1][1];
209  inverseMatrix[0][1] = -m_matrix[0][1];
210 
211 
212  inverseMatrix[1][0] = -m_matrix[1][0];
213  inverseMatrix[1][1] = m_matrix[0][0];
214 
215  inverseMatrix[2][0] = m_matrix[1][0] * m_matrix[2][1] - m_matrix[2][0] * m_matrix[1][1];
216  inverseMatrix[2][1] = -( m_matrix[0][0] * m_matrix[2][1] - m_matrix[2][0] * m_matrix[0][1] );
217 
218  inverseMatrix[0][0] /= det; inverseMatrix[1][0] /= det; inverseMatrix[2][0] /= det;
219  inverseMatrix[0][1] /= det; inverseMatrix[1][1] /= det; inverseMatrix[2][1] /= det;
220 
221  int i, j;
222  for ( i = 0; i < 3; i++ )
223  {
224  for ( j = 0; j < 2; j++ )
225  {
226  m_matrix[i][j] = inverseMatrix[i][j];
227  }
228  }
229 
231  return true;
232  }
233  else if( m_matrix[0][0] && !m_matrix[1][0] && !m_matrix[0][1] && !m_matrix[1][1] )
234  {
235  // We cannot realy invert this, but it is a 1D degenerated case, that can be 1D inverted
236  m_matrix[0][0] = 1 / m_matrix[0][0];
237  m_matrix[2][0] = -m_matrix[0][0] * m_matrix[2][0];
238  m_matrix[2][1] = -m_matrix[2][1];
239  return true;
240  }
241  else if( !m_matrix[0][0] && !m_matrix[1][0] && !m_matrix[0][1] && m_matrix[1][1] )
242  {
243  // We cannot realy invert this, but it is a 1D degenerated case, that can be 1D inverted
244  m_matrix[1][1] = 1 / m_matrix[1][1];
245  m_matrix[2][1] = -m_matrix[1][1] * m_matrix[2][1];
246  m_matrix[2][0] = -m_matrix[2][0];
247  return true;
248  }
249  else
250  {
251  return false;
252  }
253 }
254 
255 // Make into identity matrix
257 {
258  m_matrix[0][0] = m_matrix[1][1] = 1.0;
259  m_matrix[1][0] = m_matrix[2][0] = m_matrix[0][1] = m_matrix[2][1] = 0.0;
260  m_isIdentity = true;
261 
262  return true;
263 }
264 
265 // Scale by scale (isotropic scaling i.e. the same in x and y):
266 // | scale 0 0 |
267 // matrix' = | 0 scale 0 | x matrix
268 // | 0 0 scale |
269 //
270 bool a2dAffineMatrix::Scale( double scale )
271 {
272  int i, j;
273  for ( i = 0; i < 3; i++ )
274  {
275  for ( j = 0; j < 2; j++ )
276  {
277  m_matrix[i][j] *= scale;
278  }
279  }
281 
282  return true;
283 }
284 
285 // Remove Scale:
286 // | 1/sqrt(det) 0 0 |
287 // matrix' = | 0 1/sqrt(det) 0 | x matrix
288 // | 0 0 1 |
289 //
291 {
292  if ( m_isIdentity )
293  return true;
294  double scale = sqrt( fabs( m_matrix[0][0] * m_matrix[1][1] - m_matrix[0][1] * m_matrix[1][0] ) );
295  if( scale )
296  {
297  int i, j;
298  for ( i = 0; i < 2; i++ )
299  {
300  for ( j = 0; j < 2; j++ )
301  {
302  m_matrix[i][j] /= scale;
303  }
304  }
305  for ( j = 0; j < 2; j++ )
306  {
307  double scaleJ = sqrt( m_matrix[0][j] * m_matrix[0][j] + m_matrix[1][j] * m_matrix[1][j] );
308  wxASSERT_MSG( scaleJ != 0, wxT( "matrix scaleJ == 0 !" ) );
309  m_matrix[0][j] /= scaleJ;
310  m_matrix[1][j] /= scaleJ;
311  }
313 
314  return true;
315  }
316  wxASSERT_MSG( scale != 0, wxT( "matrix determinant == 0 !" ) );
317  return false;
318 }
319 
320 
321 // scale a matrix in 2D
322 //
323 // xs 0 xc(1-xs)
324 // 0 ys yc(1-ys)
325 // 0 0 1
326 //
327 a2dAffineMatrix& a2dAffineMatrix::Scale( const double& xs, const double& ys, const double& xc, const double& yc )
328 {
329  double r00, r10, r20, r01, r11, r21;
330 
331  if ( m_isIdentity )
332  {
333  double tx = xc * ( 1 - xs );
334  double ty = yc * ( 1 - ys );
335  r00 = xs;
336  r10 = 0;
337  r20 = tx;
338  r01 = 0;
339  r11 = ys;
340  r21 = ty;
341  }
342  else if ( xc != 0 || yc != 0 )
343  {
344  double tx = xc * ( 1 - xs );
345  double ty = yc * ( 1 - ys );
346  r00 = xs * m_matrix[0][0];
347  r10 = xs * m_matrix[1][0];
348  r20 = xs * m_matrix[2][0] + tx;
349  r01 = ys * m_matrix[0][1];
350  r11 = ys * m_matrix[1][1];
351  r21 = ys * m_matrix[2][1] + ty;
352  }
353  else
354  {
355  r00 = xs * m_matrix[0][0];
356  r10 = xs * m_matrix[1][0];
357  r20 = xs * m_matrix[2][0];
358  r01 = ys * m_matrix[0][1];
359  r11 = ys * m_matrix[1][1];
360  r21 = ys * m_matrix[2][1];
361  }
362 
363  m_matrix[0][0] = r00;
364  m_matrix[1][0] = r10;
365  m_matrix[2][0] = r20;
366  m_matrix[0][1] = r01;
367  m_matrix[1][1] = r11;
368  m_matrix[2][1] = r21;
369 
370  /* or like this
371  // first translate to origin O
372  (*this).Translate(-x_cen, -y_cen);
373 
374  // now do the scaling
375  a2dAffineMatrix scale;
376  scale.m_matrix[0][0] = x_fac;
377  scale.m_matrix[1][1] = y_fac;
378  scale.m_isIdentity = IsIdentity1();
379 
380  *this = scale * (*this);
381 
382  // translate back from origin to x_cen, y_cen
383  (*this).Translate(x_cen, y_cen);
384  */
385 
387 
388  return *this;
389 }
390 
391 
392 // mirror a matrix in x, y
393 //
394 // -1 0 0 X-mirror
395 // 0 -1 0 Y-mirror
397 {
398  a2dAffineMatrix temp;
399  if ( x )
400  {
401  temp.m_matrix[0][0] = -1;
402  temp.m_isIdentity = false;
403  }
404  if ( y )
405  {
406  temp.m_matrix[1][1] = -1;
407  temp.m_isIdentity = false;
408  }
409 
410  *this = temp * ( *this );
412  return *this;
413 }
414 
415 // Translate by dx, dy:
416 // | 1 0 dx |
417 // matrix' = | 0 1 dy | x matrix
418 // | 0 0 1 |
419 //
420 bool a2dAffineMatrix::Translate( double dx, double dy )
421 {
422  m_matrix[2][0] += dx;
423  m_matrix[2][1] += dy;
425  return true;
426 }
427 
428 // Rotate clockwise by the given number of degrees:
429 // | cos sin 0 |
430 // matrix' = | -sin cos 0 | x matrix
431 // | 0 0 1 |
432 bool a2dAffineMatrix::Rotate( double degrees )
433 {
434  if ( degrees == 0 )
435  return true;
436 
437  Rotate( -degrees, 0, 0 );
438  return true;
439 }
440 
441 bool a2dAffineMatrix::SkewX( double degrees )
442 {
443  if ( degrees == 0 )
444  return true;
445 
446  double angle = degrees * wxPI / 180.0;
447  double t = tan( angle );
448 
449  a2dAffineMatrix skew;
450 
451  skew.m_matrix[1][0] = t;
452  skew.m_isIdentity = false;
453 
454  *this = skew * ( *this );
455 
457  return true;
458 }
459 
460 bool a2dAffineMatrix::SkewY( double degrees )
461 {
462  if ( degrees == 0 )
463  return true;
464 
465  double angle = degrees * wxPI / 180.0;
466  double t = tan( angle );
467 
468  a2dAffineMatrix skew;
469 
470  skew.m_matrix[0][1] = t;
471  skew.m_isIdentity = false;
472 
473  *this = skew * ( *this );
474 
476  return true;
477 }
478 
479 // counter clockwise rotate around a point
480 //
481 // cos(r) -sin(r) x(1-cos(r))+y(sin(r)
482 // sin(r) cos(r) y(1-cos(r))-x(sin(r)
483 // 0 0 1
484 a2dAffineMatrix& a2dAffineMatrix::Rotate( const double& degrees, const double& x, const double& y )
485 {
486  if ( degrees == 0 )
487  return * this;
488 
489  double angle = wxDegToRad( degrees );
490  double c = cos( angle );
491  double s = sin( angle );
492  double r00, r10, r20, r01, r11, r21;
493 
494  if ( m_isIdentity )
495  {
496  double tx = x * ( 1 - c ) + y * s;
497  double ty = y * ( 1 - c ) - x * s;
498  r00 = c ;
499  r10 = -s;
500  r20 = tx;
501  r01 = s;
502  r11 = c;
503  r21 = ty;
504  }
505  else if ( x != 0 || y != 0 )
506  {
507  double tx = x * ( 1 - c ) + y * s;
508  double ty = y * ( 1 - c ) - x * s;
509  r00 = c * m_matrix[0][0] - s * m_matrix[0][1];
510  r10 = c * m_matrix[1][0] - s * m_matrix[1][1];
511  r20 = c * m_matrix[2][0] - s * m_matrix[2][1] + tx;
512  r01 = c * m_matrix[0][1] + s * m_matrix[0][0];
513  r11 = c * m_matrix[1][1] + s * m_matrix[1][0];
514  r21 = c * m_matrix[2][1] + s * m_matrix[2][0] + ty;
515  }
516  else
517  {
518  r00 = c * m_matrix[0][0] - s * m_matrix[0][1];
519  r10 = c * m_matrix[1][0] - s * m_matrix[1][1];
520  r20 = c * m_matrix[2][0] - s * m_matrix[2][1];
521  r01 = c * m_matrix[0][1] + s * m_matrix[0][0];
522  r11 = c * m_matrix[1][1] + s * m_matrix[1][0];
523  r21 = c * m_matrix[2][1] + s * m_matrix[2][0];
524  }
525 
526  m_matrix[0][0] = r00;
527  m_matrix[1][0] = r10;
528  m_matrix[2][0] = r20;
529  m_matrix[0][1] = r01;
530  m_matrix[1][1] = r11;
531  m_matrix[2][1] = r21;
532 
533  /* or like this
534  double angle = degrees * pi / 180.0;
535  double c = cos(angle);
536  double s = sin(angle);
537  double tx = x*(1-c)+y*s;
538  double ty = y*(1-c)-x*s;
539 
540  a2dAffineMatrix rotate;
541  rotate.m_matrix[2][0] = tx;
542  rotate.m_matrix[2][1] = ty;
543 
544  rotate.m_matrix[0][0] = c;
545  rotate.m_matrix[0][1] = s;
546 
547  rotate.m_matrix[1][0] = -s;
548  rotate.m_matrix[1][1] = c;
549 
550  rotate.m_isIdentity=false;
551  *this = rotate * (*this);
552  */
554 
555  return *this;
556 }
557 
558 // Transform a point from logical to device coordinates
559 void a2dAffineMatrix::TransformPoint( double x, double y, double& tx, double& ty ) const
560 {
561  if ( m_isIdentity )
562  {
563  tx = x; ty = y; return;
564  }
565 
566  tx = x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0];
567  ty = x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1];
568 }
569 
570 // Transform a point from logical to device coordinates
571 void a2dAffineMatrix::TransformPoint( double& tx, double& ty ) const
572 {
573  if ( m_isIdentity )
574  return;
575 
576  tx = tx * m_matrix[0][0] + ty * m_matrix[1][0] + m_matrix[2][0];
577  ty = tx * m_matrix[0][1] + ty * m_matrix[1][1] + m_matrix[2][1];
578 }
579 
581 {
582  if ( m_isIdentity )
583  return;
584 
585  double x = point->m_x * m_matrix[0][0] + point->m_y * m_matrix[1][0] + m_matrix[2][0];
586  point->m_y = point->m_x * m_matrix[0][1] + point->m_y * m_matrix[1][1] + m_matrix[2][1];
587  point->m_x = x;
588 }
589 
591 {
592  if ( m_isIdentity )
593  {
594  *dest = src;
595  return;
596  }
597 
598  dest->m_x = src.m_x * m_matrix[0][0] + src.m_y * m_matrix[1][0] + m_matrix[2][0];
599  dest->m_y = src.m_x * m_matrix[0][1] + src.m_y * m_matrix[1][1] + m_matrix[2][1];
600 }
601 
602 void a2dAffineMatrix::TransformVector( double dx, double dy, double& tdx, double& tdy ) const
603 {
604  if ( m_isIdentity )
605  {
606  tdx = dx; tdy = dy; return;
607  }
608  // consider two points (px,py) and (px+dx,py+dy), transform both and subtract
609  // to get the new vector. In 2D homogeneous coords, also equiv to
610  // mtx * [dx,dy,0], instead of mtx * [x,y,1] for a point.
611 
612  tdx = dx * m_matrix[0][0] + dy * m_matrix[1][0];
613  tdy = dx * m_matrix[0][1] + dy * m_matrix[1][1];
614 }
615 
616 double a2dAffineMatrix::TransformDistance( double distance ) const
617 {
618  if ( m_isIdentity )
619  return distance;
620  /*
621  fill in (0,0) for one point, and (0,distance) or (distance,0) for the second
622 
623  tx = x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0];
624  ty = x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1];
625 
626  and you get
627 
628  xt = dx * m_matrix[0][0] + dy * m_matrix[1][0];
629  yt = dx * m_matrix[0][1] + dy * m_matrix[1][1];
630  */
631 
632  return wxMin( sqrt( m_matrix[0][0] * m_matrix[0][0] + m_matrix[0][1] * m_matrix[0][1] ) * distance,
633  sqrt( m_matrix[1][0] * m_matrix[1][0] + m_matrix[1][1] * m_matrix[1][1] ) * distance );
634 }
635 
636 void a2dAffineMatrix::TransformDistance( double& dx, double& dy ) const
637 {
638  /*
639  fill in (0,0) for one point, and (dx,dy) for the second
640 
641  tx = x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0];
642  ty = x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1];
643 
644  and you get
645 
646  xt = dx * m_matrix[0][0] + dy * m_matrix[1][0];
647  yt = dy * m_matrix[0][1] + dy * m_matrix[1][1];
648  */
649  double xt = dx * m_matrix[0][0] + dy * m_matrix[1][0];
650  double yt = dx * m_matrix[0][1] + dy * m_matrix[1][1];
651  dx = xt;
652  dy = yt;
653 }
654 
656 {
657  if ( mat.m_isIdentity )
658  return * this;
659  if ( m_isIdentity )
660  {
661  *this = mat;
662  return *this;
663  }
664  else
665  {
666  a2dAffineMatrix result;
667  for ( int i = 0; i < 2; i++ )
668  {
669  double sum;
670 
671  sum = m_matrix[0][i] * mat.m_matrix[0][0];
672  sum += m_matrix[1][i] * mat.m_matrix[0][1];
673  result.m_matrix[0][i] = sum;
674 
675  sum = m_matrix[0][i] * mat.m_matrix[1][0];
676  sum += m_matrix[1][i] * mat.m_matrix[1][1];
677  result.m_matrix[1][i] = sum;
678 
679  sum = m_matrix[0][i] * mat.m_matrix[2][0];
680  sum += m_matrix[1][i] * mat.m_matrix[2][1];
681  sum += m_matrix[2][i];
682  result.m_matrix[2][i] = sum;
683  }
684  *this = result;
685  }
686 
688  return *this;
689 
690 }
691 
693 {
694  if ( mat.m_isIdentity )
695  return * this;
696  if ( m_isIdentity )
697  {
698  return mat;
699  }
700  else
701  {
702  a2dAffineMatrix result;
703  for ( int i = 0; i < 2; i++ )
704  {
705  double sum;
706 
707  sum = m_matrix[0][i] * mat.m_matrix[0][0];
708  sum += m_matrix[1][i] * mat.m_matrix[0][1];
709  result.m_matrix[0][i] = sum;
710 
711  sum = m_matrix[0][i] * mat.m_matrix[1][0];
712  sum += m_matrix[1][i] * mat.m_matrix[1][1];
713  result.m_matrix[1][i] = sum;
714 
715  sum = m_matrix[0][i] * mat.m_matrix[2][0];
716  sum += m_matrix[1][i] * mat.m_matrix[2][1];
717  sum += m_matrix[2][i];
718  result.m_matrix[2][i] = sum;
719  }
720  result.m_isIdentity = result.IsIdentity1();
721  return result;
722  }
723 }
724 
725 //! matrixes subtract
727 {
729  ret;
730  ret.m_matrix[0][0] = m_matrix[0][0] - b.m_matrix[0][0];
731  ret.m_matrix[0][1] = m_matrix[0][1] - b.m_matrix[0][1];
732  ret.m_matrix[1][0] = m_matrix[1][0] - b.m_matrix[1][0];
733  ret.m_matrix[1][1] = m_matrix[1][1] - b.m_matrix[1][1];
734  ret.m_matrix[2][0] = m_matrix[2][0] - b.m_matrix[2][0];
735  ret.m_matrix[2][1] = m_matrix[2][1] - b.m_matrix[2][1];
736 
737  return ret;
738 }
739 
740 //! matrixes subtract
741 A2DARTBASEDLLEXP a2dAffineMatrix operator-( const a2dAffineMatrix& a, const a2dAffineMatrix& b )
742 {
744  ret;
745  ret.m_matrix[0][0] = a.m_matrix[0][0] - b.m_matrix[0][0];
746  ret.m_matrix[0][1] = a.m_matrix[0][1] - b.m_matrix[0][1];
747  ret.m_matrix[1][0] = a.m_matrix[1][0] - b.m_matrix[1][0];
748  ret.m_matrix[1][1] = a.m_matrix[1][1] - b.m_matrix[1][1];
749  ret.m_matrix[2][0] = a.m_matrix[2][0] - b.m_matrix[2][0];
750  ret.m_matrix[2][1] = a.m_matrix[2][1] - b.m_matrix[2][1];
751 
752  return ret;
753 }
754 
756 {
757  if ( IsIdentity() )
758  return 1;
759 
760  double rot_angle = atan2( m_matrix[0][1], m_matrix[0][0] ) * 180 / wxPI;
761  a2dAffineMatrix inverse;
762  inverse.Rotate( -rot_angle, m_matrix[2][0], m_matrix[2][1] );
763 
764  a2dAffineMatrix h = *this;
765  h *= inverse;
766 
767 
768  double scale_factor;
769  scale_factor = h.GetValue( 0, 0 );
770 
771  if ( scale_factor < 0 )
772  scale_factor = -scale_factor;
773 
774  return scale_factor;
775 }
776 
778 {
779  if ( IsIdentity() )
780  return 1;
781 
782  double rot_angle = atan2( m_matrix[0][1], m_matrix[0][0] ) * 180 / wxPI;
783  a2dAffineMatrix inverse;
784  inverse.Rotate( -rot_angle, m_matrix[2][0], m_matrix[2][1] );
785 
786  a2dAffineMatrix h = *this;
787  h *= inverse;
788 
789 
790  double scale_factor;
791  scale_factor = h.GetValue( 1, 1 );
792 
793  if ( scale_factor < 0 )
794  scale_factor = -scale_factor;
795 
796  return scale_factor;
797 }
798 
800 {
801  if ( IsIdentity() )
802  return 0.0;
803 
804  double temp1 = m_matrix[0][0]; // for angle calculation
805  double temp2 = m_matrix[0][1]; //
806 
807  // Rotation
808  double rot_angle = atan2( temp2, temp1 ) * 180 / wxPI;
809  if ( rot_angle == -180.0 )
810  rot_angle = 180.0;
811 
812  return rot_angle;
813 }
814 
815 void a2dAffineMatrix::SetRotation( double rotation )
816 {
817  double x = m_matrix[2][0];
818  double y = m_matrix[2][1];
819  if ( !IsIdentity() )
820  Rotate( -GetRotation(), x, y );
821 
822  Rotate( rotation, x, y );
823 }
824 
826 {
827  return m_matrix[0][0] * m_matrix[1][1] - m_matrix[1][0] * m_matrix[0][1];
828 }
829 
831 {
832  return m_matrix[2][0] * m_matrix[1][1] - m_matrix[1][0] * m_matrix[2][1];
833 }
834 
836 {
837  return m_matrix[0][0] * m_matrix[2][1] - m_matrix[2][0] * m_matrix[0][1];
838 }
839 
841 {
842  return
843  wxMax(
844  wxMax( fabs( m_matrix[0][0] ), fabs( m_matrix[1][1] ) ),
845  wxMax( fabs( m_matrix[1][0] ), fabs( m_matrix[0][1] ) )
846  );
847 }
848 
850 {
851  return
852  wxMax(
853  wxMax( fabs( m_matrix[2][0] ), fabs( m_matrix[1][1] ) ),
854  wxMax( fabs( m_matrix[1][0] ), fabs( m_matrix[2][1] ) )
855  );
856 }
857 
859 {
860  return
861  wxMax(
862  wxMax( fabs( m_matrix[0][0] ), fabs( m_matrix[2][1] ) ),
863  wxMax( fabs( m_matrix[2][0] ), fabs( m_matrix[0][1] ) )
864  );
865 }
866 
867 void a2dAffineMatrix::DebugDump( const wxChar* text, double w, double h ) const
868 {
869  wxLogDebug( text );
870  wxLogDebug( wxT( "a00=%12.6lf, a01=%12.6lf" ), m_matrix[0][0], m_matrix[0][1] );
871  wxLogDebug( wxT( "a10=%12.6lf, a11=%12.6lf" ), m_matrix[1][0], m_matrix[1][1] );
872  wxLogDebug( wxT( "a20=%12.6lf. a21=%12.6lf" ), m_matrix[2][0], m_matrix[2][1] );
873  wxLogDebug( wxT( "w =%12.6lf, h =%12.6lf" ), w, h );
874  wxLogDebug( wxT( "cx =%12.6lf, cy =%12.6lf" ),
875  0.5 * ( m_matrix[0][0] * w + m_matrix[1][0] * h ) + m_matrix[2][0],
876  0.5 * ( m_matrix[0][1] * w + m_matrix[1][1] * h ) + m_matrix[2][1]
877  );
878  wxLogDebug( wxT( "lx =%12.6lf, ly =%12.6lf" ),
879  w * sqrt( m_matrix[0][0] * m_matrix[0][0] + m_matrix[0][1] * m_matrix[0][1] ),
880  h * sqrt( m_matrix[1][0] * m_matrix[1][0] + m_matrix[1][1] * m_matrix[1][1] )
881  );
882  wxLogDebug( wxT( "\n" ) );
883 }
884 
885 // The default constructor makes it an identity matrix
887 
888 
889 //***************************** functies used global ********************************
890 A2DARTBASEDLLEXP bool ParseCvgTransForm( a2dAffineMatrix& matrix, const wxString& str, wxString& error )
891 {
892  if ( str == wxT( "" ) )
893  return false;
894 
895  wxString numstr;
896  double matrixcoef[12];
897  int nr_matrixcoef;
898 
899  wxString keywstr;
900  size_t i;
901  for ( i = 0; i < str.Len(); i++ )
902  {
903  //skip space
904  while ( wxIsspace( str[i] ) ) i++;
905 
906  nr_matrixcoef = 0;
907  keywstr.Clear();
908  //transform keyword
909  while ( i < str.Len() && isalpha ( str[i] ) )
910  {
911  keywstr += str.GetChar( i );
912  i++;
913  }
914 
915  //skip space
916  while ( wxIsspace( str[i] ) ) i++;
917 
918  if ( str[i] != wxT( '(' ) )
919  {
920  error = _( "CVG parsing error: missing" );
921  return false;
922  }
923  i++;
924 
925  while ( wxIsspace( str[i] ) ) i++;
926 
927  while ( i < str.Len() && str[i] != wxT( ')' ) )
928  {
929  numstr.Clear();
930  while ( i < str.Len() && ( isdigit( str[i] ) || str[i] == wxT( '+' ) || str[i] == wxT( '-' ) || str[i] == wxT( '.' ) || str[i] == wxT( 'e' ) || str[i] == wxT( 'E' ) ) )
931  {
932  numstr += str.GetChar( i );
933  i++;
934  }
935  numstr.ToDouble( &matrixcoef[nr_matrixcoef] );
936  nr_matrixcoef++;
937  while ( i < str.Len() && ( wxIsspace( str[i] ) || str[i] == wxT( ',' ) ) ) i++;
938  }
939 
940  if ( str[i] != wxT( ')' ) )
941  {
942  error = _( "CVG parsing error: missing" );
943  return false;
944  }
945  i++;
946 
947  if ( keywstr == wxT( "matrix" ) )
948  {
949  if ( nr_matrixcoef != 6 )
950  {
951  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
952  return false;
953  }
954  matrix.SetValue( 0, 0, matrixcoef[0] );
955  matrix.SetValue( 0, 1, matrixcoef[1] );
956  matrix.SetValue( 1, 0, matrixcoef[2] );
957  matrix.SetValue( 1, 1, matrixcoef[3] );
958  matrix.SetValue( 2, 0, matrixcoef[4] );
959  matrix.SetValue( 2, 1, matrixcoef[5] );
960  }
961  else if ( keywstr == wxT( "translate" ) )
962  {
963  if ( nr_matrixcoef == 1 )
964  matrix.Translate( matrixcoef[0] , 0 );
965  else if ( nr_matrixcoef != 2 )
966  {
967  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
968  return false;
969  }
970  else
971  matrix.Translate( matrixcoef[0] , matrixcoef[1] );
972  }
973  else if ( keywstr == wxT( "scale" ) )
974  {
975  if ( nr_matrixcoef == 1 )
976  matrix.Scale( matrixcoef[0], 1.0, matrix.GetValue( 2, 0 ), matrix.GetValue( 2, 1 ) );
977  else if ( nr_matrixcoef != 2 )
978  {
979  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
980  return false;
981  }
982  else
983  matrix.Scale( matrixcoef[0], matrixcoef[1], matrix.GetValue( 2, 0 ), matrix.GetValue( 2, 1 ) );
984  }
985  else if ( keywstr == wxT( "rotate" ) )
986  {
987  if ( nr_matrixcoef != 1 )
988  {
989  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
990  return false;
991  }
992  matrix.Rotate( matrixcoef[0] );
993  }
994  else if ( keywstr == wxT( "skewX" ) )
995  {
996  if ( nr_matrixcoef != 1 )
997  {
998  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
999  return false;
1000  }
1001  matrix.SkewX( matrixcoef[0] );
1002  }
1003  else if ( keywstr == wxT( "skewY" ) )
1004  {
1005  if ( nr_matrixcoef != 1 )
1006  {
1007  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
1008  return false;
1009  }
1010  matrix.SkewY( matrixcoef[0] );
1011  }
1012  else if ( keywstr == wxT( "flipX" ) )
1013  {
1014  if ( nr_matrixcoef != 0 )
1015  {
1016  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
1017  return false;
1018  }
1019  matrix.Mirror( true, false );
1020  }
1021  else if ( keywstr == wxT( "flipY" ) )
1022  {
1023  if ( nr_matrixcoef != 0 )
1024  {
1025  error.Printf( _( "CVG : wrong number of arguments %s " ), keywstr.c_str() );
1026  return false;
1027  }
1028  matrix.Mirror( false, true );
1029  }
1030  else
1031  {
1032  error.Printf( _( "CVG : invalid transform %s " ), keywstr.c_str() );
1033  return false;
1034  }
1035  }
1036  return true;
1037 }
1038 
1039 //----------------------------------------------------------------------------
1040 // a2dMatrixProperty
1041 //----------------------------------------------------------------------------
1042 
1043 a2dMatrixProperty::a2dMatrixProperty(): a2dNamedProperty()
1044 {}
1045 
1046 a2dMatrixProperty::a2dMatrixProperty( const a2dPropertyIdMatrix* id, const a2dAffineMatrix& value )
1047  : a2dNamedProperty( id )
1048 {
1049  m_value = value;
1050 }
1051 
1052 a2dMatrixProperty::a2dMatrixProperty( const a2dMatrixProperty* ori )
1053  : a2dNamedProperty( *ori )
1054 {
1055  m_value = ori->m_value;
1056 }
1057 
1058 a2dMatrixProperty::~a2dMatrixProperty()
1059 {}
1060 
1061 a2dMatrixProperty::a2dMatrixProperty( const a2dMatrixProperty& other )
1062  : a2dNamedProperty( other )
1063 {
1064  m_value = other.m_value;
1065 }
1066 
1067 a2dNamedProperty* a2dMatrixProperty::Clone( a2dObject::CloneOptions WXUNUSED( options ) ) const
1068 {
1069  return new a2dMatrixProperty( *this );
1070 };
1071 
1073 {
1074  a2dMatrixProperty* propcast = wxStaticCast( &other, a2dMatrixProperty );
1075  m_value = propcast->m_value;
1076 }
1077 
1078 #if wxART2D_USE_CVGIO
1079 void a2dMatrixProperty::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
1080 {
1081  a2dNamedProperty::DoSave( parent, out, xmlparts, towrite );
1082  if ( xmlparts == a2dXmlSer_attrib )
1083  {
1084  wxString s;
1085  s.Printf ( _T( "matrix( %g %g %g %g %g %g )" ),
1086  m_value.GetValue( 0, 0 ), m_value.GetValue( 0, 1 ),
1087  m_value.GetValue( 1, 0 ), m_value.GetValue( 1, 1 ),
1088  m_value.GetValue( 2, 0 ), m_value.GetValue( 2, 1 )
1089  );
1090  out.WriteAttribute( wxT( "transform" ), s );
1091  }
1092  else
1093  {}
1094 }
1095 
1096 void a2dMatrixProperty::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
1097 {
1098  a2dNamedProperty::DoLoad( parent, parser, xmlparts );
1099  if ( xmlparts == a2dXmlSer_attrib )
1100  {
1101  wxString str = parser.GetAttributeValue( wxT( "transform" ) );
1102  wxString error;
1103  if ( !str.IsEmpty() && !::ParseCvgTransForm( m_value, str, error ) )
1104  {
1105  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG : invalid transform %s at line %d" ), str.c_str(), parser.GetCurrentLineNumber() );
1106  }
1107  }
1108  else
1109  {}
1110 }
1111 #endif //wxART2D_USE_CVGIO
1112 
1113 void a2dMatrixProperty::SetValue( const a2dAffineMatrix& value )
1114 {
1115  m_value = value;
1116 }
1117 
1119 {
1120  wxString s;
1121  s.Printf ( wxT( "%s = matrix( %g %g %g %g %g %g )" ), m_id->GetName().c_str(),
1122  m_value.GetValue( 0, 0 ), m_value.GetValue( 0, 1 ),
1123  m_value.GetValue( 1, 0 ), m_value.GetValue( 1, 1 ),
1124  m_value.GetValue( 2, 0 ), m_value.GetValue( 2, 1 )
1125  );
1126 
1127  return s;
1128 }
1129 
1131 {
1132  wxString s;
1133  s.Printf ( _T( "matrix( %g %g %g %g %g %g )" ),
1134  m_value.GetValue( 0, 0 ), m_value.GetValue( 0, 1 ),
1135  m_value.GetValue( 1, 0 ), m_value.GetValue( 1, 1 ),
1136  m_value.GetValue( 2, 0 ), m_value.GetValue( 2, 1 )
1137  );
1138 
1139  return s;
1140 }
1141 
1143 {
1144  wxString error;
1145  a2dAffineMatrix result;
1146  if ( ::ParseCvgTransForm( result, value , error ) )
1147  return new a2dMatrixProperty( id, result );
1148  else
1149  return 0;
1150 }
1151 
1152 //----------------------------------------------------------------------------
1153 // a2dPoint2DProperty
1154 //----------------------------------------------------------------------------
1155 
1157 {}
1158 
1159 a2dPoint2DProperty::a2dPoint2DProperty( const a2dPropertyIdPoint2D* id, const a2dPoint2D& value, int index, bool afterinversion )
1160  : a2dNamedProperty( id )
1161 {
1162  m_value = value;
1163  m_index = index;
1164  m_afterinversion = afterinversion;
1165 }
1166 
1168  : a2dNamedProperty( *ori )
1169 {
1170  m_value = ori->m_value;
1171  m_index = ori->m_index;
1173 }
1174 
1176 {}
1177 
1179  : a2dNamedProperty( other )
1180 {
1181  m_value = other.m_value;
1182  m_index = other.m_index;
1184 }
1185 
1187 {
1188  return new a2dPoint2DProperty( *this );
1189 };
1190 
1192 {
1193  a2dPoint2DProperty* propcast = wxStaticCast( &other, a2dPoint2DProperty );
1194  m_value = propcast->m_value;
1195  m_index = propcast->m_index;
1196  m_afterinversion = propcast->m_afterinversion;
1197 }
1198 
1199 a2dPoint2DProperty* a2dPoint2DProperty::CreatePropertyFromString( const a2dPropertyIdPoint2D* WXUNUSED( id ), const wxString& WXUNUSED( value ) )
1200 {
1201  return 0;
1202 }
1203 
1204 #if wxART2D_USE_CVGIO
1205 void a2dPoint2DProperty::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
1206 {
1207  a2dNamedProperty::DoSave( parent, out, xmlparts, towrite );
1208  if ( xmlparts == a2dXmlSer_attrib )
1209  {
1210  out.WriteAttribute( wxT( "point2d" ), StringValueRepresentation() );
1211  }
1212  else
1213  {}
1214 }
1215 
1216 void a2dPoint2DProperty::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
1217 {
1218  a2dNamedProperty::DoLoad( parent, parser, xmlparts );
1219  if ( xmlparts == a2dXmlSer_attrib )
1220  {
1221  wxString str = parser.GetAttributeValue( wxT( "point2d" ) );
1222  wxString error;
1223  if ( !str.IsEmpty() ) //!todo && !::ParsePoint2D( m_value, str, error ) )
1224  {
1225  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG : invalid point2d %s at line %d" ), str.c_str(), parser.GetCurrentLineNumber() );
1226  }
1227  }
1228  else
1229  {}
1230 }
1231 #endif //wxART2D_USE_CVGIO
1232 
1233 void a2dPoint2DProperty::SetValue( double x, double y, int index, bool afterinversion )
1234 {
1235  m_value.m_x = x;
1236  m_value.m_y = y;
1237  m_index = index;
1238  m_afterinversion = afterinversion;
1239 }
1240 
1241 void a2dPoint2DProperty::SetValue( const a2dPoint2D& P, int index, bool afterinversion )
1242 {
1243  m_value = P;
1244  m_index = index;
1245  m_afterinversion = afterinversion;
1246 }
1247 
1249 {
1250  wxString s;
1251  s.Printf ( wxT( "%s = point2d( %f, %f, %d )" ), m_id->GetName().c_str(), m_value.m_x, m_value.m_y, m_index );
1252 
1253  if ( m_afterinversion == true )
1254  s << wxT( "true" );
1255  else
1256  s << wxT( "false" );
1257 
1258  return s;
1259 }
1260 
1262 {
1263  wxString s;
1264  s.Printf ( _T( "point2d( %f, %f, %d )" ), m_value.m_x, m_value.m_y, m_index );
1265 
1266  if ( m_afterinversion == true )
1267  s << wxT( "true" );
1268  else
1269  s << wxT( "false" );
1270 
1271  return s;
1272 }
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
a2dPoint2DProperty()
constructor
Definition: afmatrix.cpp:1156
a2dAffineMatrix & Mirror(bool y=true, bool x=false)
mirror a matrix in x, y
Definition: afmatrix.cpp:396
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
double m_matrix[3][2]
array store the six double for the affine matrix
Definition: afmatrix.h:335
property to hold a a2dAffineMatrix
Definition: afmatrix.h:410
bool RemoveScale()
Remove Scale:
Definition: afmatrix.cpp:290
virtual wxString StringRepresentation() const
a string form presentation for this property
Definition: afmatrix.cpp:1248
bool IsIdentity1(void) const
This does an actual check.
Definition: afmatrix.h:347
virtual wxString GetName() const
Get the ids print and serialization name.
Definition: id.h:245
virtual void Assign(const a2dNamedProperty &other)
Virtual assignment operator.
Definition: afmatrix.cpp:1191
static a2dPoint2DProperty * CreatePropertyFromString(const a2dPropertyIdPoint2D *id, const wxString &value)
Definition: afmatrix.cpp:1199
const a2dPropertyId * m_id
The property id object identifying this property.
Definition: gen.h:1945
bool Rotate(double angle)
Rotate clockwise by the given number of degrees:
Definition: afmatrix.cpp:432
double wxDegToRad(double deg)
conversion from degrees to radians
Definition: artglob.cpp:30
virtual int GetCurrentLineNumber()
where in the input was line the current tag
Definition: genxmlpars.cpp:349
bool IsIdentity(void) const
Is the matrix the identity matrix?
Definition: afmatrix.h:147
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
void TransformVector(double dx, double dy, double &tdx, double &tdy) const
Transform a vector.
Definition: afmatrix.cpp:602
double GetValue(int col, int row) const
get the value in the matrix at col,row
Definition: afmatrix.cpp:106
bool ParseCvgTransForm(a2dAffineMatrix &matrix, const wxString &str, wxString &error)
function to parse a string in SVG/CVG format and return the resulting matrix
Definition: afmatrix.cpp:890
a2dAffineMatrix operator-(const a2dAffineMatrix &a)
subtract two matrices
Definition: afmatrix.cpp:726
bool SkewX(double degrees)
Skew Xaxis:
Definition: afmatrix.cpp:441
void operator=(const a2dAffineMatrix &mat)
make the same
Definition: afmatrix.cpp:123
friend bool operator==(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
are they eqaul
Definition: afmatrix.cpp:140
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
Definition: afmatrix.cpp:51
property to hold a a2dPoint2D plus an index in e.g a polygon.
Definition: afmatrix.h:474
static a2dMatrixProperty * CreatePropertyFromString(const a2dPropertyIdMatrix *id, const wxString &value)
Definition: afmatrix.cpp:1142
double GetDeterminant2() const
Calculate the determinat of the transformed x-axis vector and the shift vector.
Definition: afmatrix.cpp:835
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Definition: afmatrix.cpp:559
bool m_isIdentity
true if identity matrix
Definition: afmatrix.h:338
virtual void Assign(const a2dNamedProperty &other)
Virtual assignment operator.
Definition: afmatrix.cpp:1072
double GetRotation() const
return rotation
Definition: afmatrix.cpp:799
double TransformDistance(double distance) const
Transform a distance.
Definition: afmatrix.cpp:616
static const a2dAffineMatrix sm_Identity
A static identity matrix in case an identity matrix is to be returned as reference.
Definition: afmatrix.h:342
XML I/O classes which is Pull parser based for reading XML files.
double wxCalculateDet(double a11, double a21, double a12, double a22)
Calculates the determinant of a 2 x 2 matrix.
Definition: afmatrix.cpp:191
a2dPoint2D m_value
the point that is held within this property
Definition: afmatrix.h:537
a2dAffineMatrix operator*(const a2dAffineMatrix &m) const
multiply this by matrix m and return result
Definition: afmatrix.cpp:692
virtual ~a2dPoint2DProperty()
destructor
Definition: afmatrix.cpp:1175
a2dAffineMatrix & operator*=(const a2dAffineMatrix &m)
multiply matrix m with this
Definition: afmatrix.cpp:655
double GetMaximum2() const
Calculate the maximum absolute of the elemnts entering GetDeterminant2.
Definition: afmatrix.cpp:858
const a2dError a2dError_XMLparse
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
bool SkewY(double degrees)
Skew Yaxis:
Definition: afmatrix.cpp:460
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
virtual wxString StringRepresentation() const
Definition: afmatrix.cpp:1118
bool Identity(void)
Make into identity matrix.
Definition: afmatrix.cpp:256
a2dAffineMatrix(void)
constructor (makes an identity matrix)
Definition: afmatrix.cpp:93
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
virtual wxString StringValueRepresentation() const
a string value presentation for this property
Definition: afmatrix.cpp:1261
void DebugDump(const wxChar *text, double w, double h) const
Dump the Matrix to a debug window.
Definition: afmatrix.cpp:867
double GetMaximum() const
Calculate the maximum absolute of the elemnts entering GetDeterminant.
Definition: afmatrix.cpp:840
virtual wxString StringValueRepresentation() const
Definition: afmatrix.cpp:1130
double GetDeterminant1() const
Calculate the determinat of the shift vector and the transformed y-axis vector.
Definition: afmatrix.cpp:830
double GetMaximum1() const
Calculate the maximum absolute of the elemnts entering GetDeterminant1.
Definition: afmatrix.cpp:849
double Get_scaleX() const
return scaling in X
Definition: afmatrix.cpp:755
general modules header files all together.
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
Definition: genxmlpars.cpp:450
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
Definition: afmatrix.cpp:1216
bool Scale(double scale)
Scale by scale (isotropic scaling i.e. the same in x and y):
Definition: afmatrix.cpp:270
bool Translate(double x, double y)
Translate by dx, dy:
Definition: afmatrix.cpp:420
a2dAffineMatrix operator-(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
matrixes subtract
Definition: afmatrix.cpp:741
bool Invert(void)
Invert matrix.
Definition: afmatrix.cpp:197
double GetDeterminant() const
Calculate the determinat of the linear transformation.
Definition: afmatrix.cpp:825
void SetValue(int col, int row, double value)
set the value in the matrix at col,row
Definition: afmatrix.cpp:114
affine matrix class
double Get_scaleY() const
return scaling in Y
Definition: afmatrix.cpp:777
double & operator()(int col, int row)
Definition: afmatrix.cpp:174
This template class is for property ids with a known data type.
Definition: id.h:477
void SetValue(double x, double y, int index=0, bool afterinversion=false)
set the property information to this
Definition: afmatrix.cpp:1233
void SetRotation(double rotation)
set rotation
Definition: afmatrix.cpp:815
list of a2dObject&#39;s
Definition: gen.h:3157
CloneOptions
options for cloning
Definition: gen.h:1200
a2dNamedProperty * Clone(a2dObject::CloneOptions options) const
clone
Definition: afmatrix.cpp:1186
wxInt32 m_index
Can be used as position to insert a point into a polygon.
Definition: afmatrix.h:540
const double wxPI
defines PI
Definition: artglob.cpp:28
friend bool operator!=(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
are they NOT eqaul
Definition: afmatrix.cpp:151
afmatrix.cpp Source File -- Sun Oct 12 2014 17:04:12 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation