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