matrix.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/matrix.h
  3. // Purpose: wxTransformMatrix class. NOT YET USED
  4. // Author: Chris Breeze, Julian Smart
  5. // Modified by: Klaas Holwerda
  6. // Created: 01/02/97
  7. // Copyright: (c) Julian Smart, Chris Breeze
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_MATRIXH__
  11. #define _WX_MATRIXH__
  12. //! headerfiles="matrix.h wx/object.h"
  13. #include "wx/object.h"
  14. #include "wx/math.h"
  15. //! codefiles="matrix.cpp"
  16. // A simple 3x3 matrix. This may be replaced by a more general matrix
  17. // class some day.
  18. //
  19. // Note: this is intended to be used in wxDC at some point to replace
  20. // the current system of scaling/translation. It is not yet used.
  21. //:definition
  22. // A 3x3 matrix to do 2D transformations.
  23. // It can be used to map data to window coordinates,
  24. // and also for manipulating your own data.
  25. // For example drawing a picture (composed of several primitives)
  26. // at a certain coordinate and angle within another parent picture.
  27. // At all times m_isIdentity is set if the matrix itself is an Identity matrix.
  28. // It is used where possible to optimize calculations.
  29. class WXDLLIMPEXP_CORE wxTransformMatrix: public wxObject
  30. {
  31. public:
  32. wxTransformMatrix(void);
  33. wxTransformMatrix(const wxTransformMatrix& mat);
  34. //get the value in the matrix at col,row
  35. //rows are horizontal (second index of m_matrix member)
  36. //columns are vertical (first index of m_matrix member)
  37. double GetValue(int col, int row) const;
  38. //set the value in the matrix at col,row
  39. //rows are horizontal (second index of m_matrix member)
  40. //columns are vertical (first index of m_matrix member)
  41. void SetValue(int col, int row, double value);
  42. void operator = (const wxTransformMatrix& mat);
  43. bool operator == (const wxTransformMatrix& mat) const;
  44. bool operator != (const wxTransformMatrix& mat) const;
  45. //multiply every element by t
  46. wxTransformMatrix& operator*=(const double& t);
  47. //divide every element by t
  48. wxTransformMatrix& operator/=(const double& t);
  49. //add matrix m to this t
  50. wxTransformMatrix& operator+=(const wxTransformMatrix& m);
  51. //subtract matrix m from this
  52. wxTransformMatrix& operator-=(const wxTransformMatrix& m);
  53. //multiply matrix m with this
  54. wxTransformMatrix& operator*=(const wxTransformMatrix& m);
  55. // constant operators
  56. //multiply every element by t and return result
  57. wxTransformMatrix operator*(const double& t) const;
  58. //divide this matrix by t and return result
  59. wxTransformMatrix operator/(const double& t) const;
  60. //add matrix m to this and return result
  61. wxTransformMatrix operator+(const wxTransformMatrix& m) const;
  62. //subtract matrix m from this and return result
  63. wxTransformMatrix operator-(const wxTransformMatrix& m) const;
  64. //multiply this by matrix m and return result
  65. wxTransformMatrix operator*(const wxTransformMatrix& m) const;
  66. wxTransformMatrix operator-() const;
  67. //rows are horizontal (second index of m_matrix member)
  68. //columns are vertical (first index of m_matrix member)
  69. double& operator()(int col, int row);
  70. //rows are horizontal (second index of m_matrix member)
  71. //columns are vertical (first index of m_matrix member)
  72. double operator()(int col, int row) const;
  73. // Invert matrix
  74. bool Invert(void);
  75. // Make into identity matrix
  76. bool Identity(void);
  77. // Is the matrix the identity matrix?
  78. // Only returns a flag, which is set whenever an operation
  79. // is done.
  80. inline bool IsIdentity(void) const { return m_isIdentity; }
  81. // This does an actual check.
  82. inline bool IsIdentity1(void) const ;
  83. //Scale by scale (isotropic scaling i.e. the same in x and y):
  84. //!ex:
  85. //!code: | scale 0 0 |
  86. //!code: matrix' = | 0 scale 0 | x matrix
  87. //!code: | 0 0 scale |
  88. bool Scale(double scale);
  89. //Scale with center point and x/y scale
  90. //
  91. //!ex:
  92. //!code: | xs 0 xc(1-xs) |
  93. //!code: matrix' = | 0 ys yc(1-ys) | x matrix
  94. //!code: | 0 0 1 |
  95. wxTransformMatrix& Scale(const double &xs, const double &ys,const double &xc, const double &yc);
  96. // mirror a matrix in x, y
  97. //!ex:
  98. //!code: | -1 0 0 |
  99. //!code: matrix' = | 0 -1 0 | x matrix
  100. //!code: | 0 0 1 |
  101. wxTransformMatrix& Mirror(bool x=true, bool y=false);
  102. // Translate by dx, dy:
  103. //!ex:
  104. //!code: | 1 0 dx |
  105. //!code: matrix' = | 0 1 dy | x matrix
  106. //!code: | 0 0 1 |
  107. bool Translate(double x, double y);
  108. // Rotate clockwise by the given number of degrees:
  109. //!ex:
  110. //!code: | cos sin 0 |
  111. //!code: matrix' = | -sin cos 0 | x matrix
  112. //!code: | 0 0 1 |
  113. bool Rotate(double angle);
  114. //Rotate counter clockwise with point of rotation
  115. //
  116. //!ex:
  117. //!code: | cos(r) -sin(r) x(1-cos(r))+y(sin(r)|
  118. //!code: matrix' = | sin(r) cos(r) y(1-cos(r))-x(sin(r)| x matrix
  119. //!code: | 0 0 1 |
  120. wxTransformMatrix& Rotate(const double &r, const double &x, const double &y);
  121. // Transform X value from logical to device
  122. inline double TransformX(double x) const;
  123. // Transform Y value from logical to device
  124. inline double TransformY(double y) const;
  125. // Transform a point from logical to device coordinates
  126. bool TransformPoint(double x, double y, double& tx, double& ty) const;
  127. // Transform a point from device to logical coordinates.
  128. // Example of use:
  129. // wxTransformMatrix mat = dc.GetTransformation();
  130. // mat.Invert();
  131. // mat.InverseTransformPoint(x, y, x1, y1);
  132. // OR (shorthand:)
  133. // dc.LogicalToDevice(x, y, x1, y1);
  134. // The latter is slightly less efficient if we're doing several
  135. // conversions, since the matrix is inverted several times.
  136. // N.B. 'this' matrix is the inverse at this point
  137. bool InverseTransformPoint(double x, double y, double& tx, double& ty) const;
  138. double Get_scaleX();
  139. double Get_scaleY();
  140. double GetRotation();
  141. void SetRotation(double rotation);
  142. public:
  143. double m_matrix[3][3];
  144. bool m_isIdentity;
  145. };
  146. /*
  147. Chris Breeze reported, that
  148. some functions of wxTransformMatrix cannot work because it is not
  149. known if he matrix has been inverted. Be careful when using it.
  150. */
  151. // Transform X value from logical to device
  152. // warning: this function can only be used for this purpose
  153. // because no rotation is involved when mapping logical to device coordinates
  154. // mirror and scaling for x and y will be part of the matrix
  155. // if you have a matrix that is rotated, eg a shape containing a matrix to place
  156. // it in the logical coordinate system, use TransformPoint
  157. inline double wxTransformMatrix::TransformX(double x) const
  158. {
  159. //normally like this, but since no rotation is involved (only mirror and scale)
  160. //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero
  161. //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0]))
  162. return (m_isIdentity ? x : (x * m_matrix[0][0] + m_matrix[2][0]));
  163. }
  164. // Transform Y value from logical to device
  165. // warning: this function can only be used for this purpose
  166. // because no rotation is involved when mapping logical to device coordinates
  167. // mirror and scaling for x and y will be part of the matrix
  168. // if you have a matrix that is rotated, eg a shape containing a matrix to place
  169. // it in the logical coordinate system, use TransformPoint
  170. inline double wxTransformMatrix::TransformY(double y) const
  171. {
  172. //normally like this, but since no rotation is involved (only mirror and scale)
  173. //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero
  174. //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1]))
  175. return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1]));
  176. }
  177. // Is the matrix the identity matrix?
  178. // Each operation checks whether the result is still the identity matrix and sets a flag.
  179. inline bool wxTransformMatrix::IsIdentity1(void) const
  180. {
  181. return
  182. ( wxIsSameDouble(m_matrix[0][0], 1.0) &&
  183. wxIsSameDouble(m_matrix[1][1], 1.0) &&
  184. wxIsSameDouble(m_matrix[2][2], 1.0) &&
  185. wxIsSameDouble(m_matrix[1][0], 0.0) &&
  186. wxIsSameDouble(m_matrix[2][0], 0.0) &&
  187. wxIsSameDouble(m_matrix[0][1], 0.0) &&
  188. wxIsSameDouble(m_matrix[2][1], 0.0) &&
  189. wxIsSameDouble(m_matrix[0][2], 0.0) &&
  190. wxIsSameDouble(m_matrix[1][2], 0.0) );
  191. }
  192. // Calculates the determinant of a 2 x 2 matrix
  193. inline double wxCalculateDet(double a11, double a21, double a12, double a22)
  194. {
  195. return a11 * a22 - a12 * a21;
  196. }
  197. #endif // _WX_MATRIXH__