]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/matrix.h
don't use DECLARE_EVENT_TYPE() to avoid confusing people about its unused value param...
[wxWidgets.git] / include / wx / matrix.h
index 1c5b592778dca52c78a46ad0a05261775d16a74a..465846e8d9ffae9d1a7effe17abb11c8c7538b96 100644 (file)
@@ -1,22 +1,22 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        matrix.h
-// Purpose:     wxTransformMatrix class. NOT YET USED
-// Author:      Chris Breeze, Julian Smart
-// Modified by:
-// Created:     01/02/97
-// RCS-ID:      $Id$
-// Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows licence
+// Name:         wx/matrix.h
+// Purpose:      wxTransformMatrix class. NOT YET USED
+// Author:       Chris Breeze, Julian Smart
+// Modified by:  Klaas Holwerda
+// Created:      01/02/97
+// RCS-ID:       $Id$
+// Copyright:    (c) Julian Smart, Chris Breeze
+// Licence:      wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __MATRIXH__
-#define __MATRIXH__
-
-#ifdef __GNUG__
-#pragma interface "matrix.h"
-#endif
+#ifndef _WX_MATRIXH__
+#define _WX_MATRIXH__
 
+//! headerfiles="matrix.h wx/object.h"
 #include "wx/object.h"
+#include "wx/math.h"
+
+//! codefiles="matrix.cpp"
 
 // A simple 3x3 matrix. This may be replaced by a more general matrix
 // class some day.
 // Note: this is intended to be used in wxDC at some point to replace
 // the current system of scaling/translation. It is not yet used.
 
+//:definition
+//  A 3x3 matrix to do 2D transformations.
+//  It can be used to map data to window coordinates,
+//  and also for manipulating your own data.
+//  For example drawing a picture (composed of several primitives)
+//  at a certain coordinate and angle within another parent picture.
+//  At all times m_isIdentity is set if the matrix itself is an Identity matrix.
+//  It is used where possible to optimize calculations.
 class WXDLLEXPORT wxTransformMatrix: public wxObject
 {
 public:
-       wxTransformMatrix(void);
-       wxTransformMatrix(const wxTransformMatrix& mat);
-
-       double GetValue(int row, int col) const;
-       void SetValue(int row, int col, double value);
-
-       void operator = (const wxTransformMatrix& mat);
-       bool operator == (const wxTransformMatrix& mat);
-       bool operator != (const wxTransformMatrix& mat);
-
-       double& operator()(int row, int col);
-       double operator()(int row, int col) const;
-
-       // Invert matrix
-       bool Invert(void);
-
-       // Make into identity matrix
-       bool Identity(void);
-
-       // Is the matrix the identity matrix?
-       // Only returns a flag, which is set whenever an operation
-       // is done.
-       inline bool IsIdentity(void) const { return m_isIdentity; };
-
-       // This does an actual check.
-       inline bool IsIdentity1(void) const ;
-
-       // Isotropic scaling
-       bool Scale(double scale);
-
-       // Translate
-       bool Translate(double x, double y);
+    wxTransformMatrix(void);
+    wxTransformMatrix(const wxTransformMatrix& mat);
+
+    //get the value in the matrix at col,row
+    //rows are horizontal (second index of m_matrix member)
+    //columns are vertical (first index of m_matrix member)
+    double GetValue(int col, int row) const;
+
+    //set the value in the matrix at col,row
+    //rows are horizontal (second index of m_matrix member)
+    //columns are vertical (first index of m_matrix member)
+    void SetValue(int col, int row, double value);
+
+    void operator = (const wxTransformMatrix& mat);
+    bool operator == (const wxTransformMatrix& mat) const;
+    bool operator != (const wxTransformMatrix& mat) const;
+
+    //multiply every element by t
+    wxTransformMatrix&          operator*=(const double& t);
+    //divide every element by t
+    wxTransformMatrix&          operator/=(const double& t);
+    //add matrix m to this t
+    wxTransformMatrix&          operator+=(const wxTransformMatrix& m);
+    //subtract matrix m from this
+    wxTransformMatrix&          operator-=(const wxTransformMatrix& m);
+    //multiply matrix m with this
+    wxTransformMatrix&          operator*=(const wxTransformMatrix& m);
+
+    // constant operators
+
+    //multiply every element by t  and return result
+    wxTransformMatrix           operator*(const double& t) const;
+    //divide this matrix by t and return result
+    wxTransformMatrix           operator/(const double& t) const;
+    //add matrix m to this and return result
+    wxTransformMatrix           operator+(const wxTransformMatrix& m) const;
+    //subtract matrix m from this and return result
+    wxTransformMatrix           operator-(const wxTransformMatrix& m) const;
+    //multiply this by matrix m and return result
+    wxTransformMatrix           operator*(const wxTransformMatrix& m) const;
+    wxTransformMatrix           operator-() const;
+
+    //rows are horizontal (second index of m_matrix member)
+    //columns are vertical (first index of m_matrix member)
+    double& operator()(int col, int row);
+
+    //rows are horizontal (second index of m_matrix member)
+    //columns are vertical (first index of m_matrix member)
+    double operator()(int col, int row) const;
+
+    // Invert matrix
+    bool Invert(void);
+
+    // Make into identity matrix
+    bool Identity(void);
+
+    // Is the matrix the identity matrix?
+    // Only returns a flag, which is set whenever an operation
+    // is done.
+    inline bool IsIdentity(void) const { return m_isIdentity; }
+
+    // This does an actual check.
+    inline bool IsIdentity1(void) const ;
+
+    //Scale by scale (isotropic scaling i.e. the same in x and y):
+    //!ex:
+    //!code:           | scale  0      0      |
+    //!code: matrix' = |  0     scale  0      | x matrix
+    //!code:           |  0     0      scale  |
+    bool Scale(double scale);
+
+    //Scale with center point and x/y scale
+    //
+    //!ex:
+    //!code:           |  xs    0      xc(1-xs) |
+    //!code: matrix' = |  0    ys      yc(1-ys) | x matrix
+    //!code:           |  0     0      1        |
+    wxTransformMatrix&  Scale(const double &xs, const double &ys,const double &xc, const double &yc);
+
+    // mirror a matrix in x, y
+    //!ex:
+    //!code:           | -1     0      0 |
+    //!code: matrix' = |  0    -1      0 | x matrix
+    //!code:           |  0     0      1 |
+    wxTransformMatrix&  Mirror(bool x=true, bool y=false);
+    // Translate by dx, dy:
+    //!ex:
+    //!code:           | 1  0 dx |
+    //!code: matrix' = | 0  1 dy | x matrix
+    //!code:           | 0  0  1 |
+    bool Translate(double x, double y);
+
+    // Rotate clockwise by the given number of degrees:
+    //!ex:
+    //!code:           |  cos sin 0 |
+    //!code: matrix' = | -sin cos 0 | x matrix
+    //!code:           |   0   0  1 |
+    bool Rotate(double angle);
+
+    //Rotate counter clockwise with point of rotation
+    //
+    //!ex:
+    //!code:           |  cos(r) -sin(r)    x(1-cos(r))+y(sin(r)|
+    //!code: matrix' = |  sin(r)  cos(r)    y(1-cos(r))-x(sin(r)| x matrix
+    //!code:           |   0          0                       1 |
+    wxTransformMatrix&  Rotate(const double &r, const double &x, const double &y);
+
+    // Transform X value from logical to device
+    inline double TransformX(double x) const;
+
+    // Transform Y value from logical to device
+    inline double TransformY(double y) const;
+
+    // Transform a point from logical to device coordinates
+    bool TransformPoint(double x, double y, double& tx, double& ty) const;
+
+    // Transform a point from device to logical coordinates.
+    // Example of use:
+    //   wxTransformMatrix mat = dc.GetTransformation();
+    //   mat.Invert();
+    //   mat.InverseTransformPoint(x, y, x1, y1);
+    // OR (shorthand:)
+    //   dc.LogicalToDevice(x, y, x1, y1);
+    // The latter is slightly less efficient if we're doing several
+    // conversions, since the matrix is inverted several times.
+    // N.B. 'this' matrix is the inverse at this point
+    bool InverseTransformPoint(double x, double y, double& tx, double& ty) const;
+
+    double Get_scaleX();
+    double Get_scaleY();
+    double GetRotation();
+    void   SetRotation(double rotation);
 
-       // Rotate
-       bool Rotate(double angle);
 
-       // Transform X value from logical to device
-       inline double TransformX(double x) const;
-
-       // Transform Y value from logical to device
-       inline double TransformY(double y) const;
-
-       // Transform a point from logical to device coordinates
-       bool TransformPoint(double x, double y, double& tx, double& ty) const;
-
-       // Transform a point from device to logical coordinates.
-
-       // Example of use:
-       //   wxTransformMatrix mat = dc.GetTransformation();
-       //   mat.Invert();
-       //   mat.InverseTransformPoint(x, y, x1, y1);
-       // OR (shorthand:)
-       //   dc.LogicalToDevice(x, y, x1, y1);
-       // The latter is slightly less efficient if we're doing several
-       // conversions, since the matrix is inverted several times.
-
-       // N.B. 'this' matrix is the inverse at this point
+public:
+    double  m_matrix[3][3];
+    bool    m_isIdentity;
+};
 
-       bool InverseTransformPoint(double x, double y, double& tx, double& ty) const;
 
-public:
-    double     m_matrix[3][3];
-       bool    m_isIdentity;
 /*
-       double m11, m21, m31;
-       double m12, m22, m32;
-       double m13, m23, m33;
+Chris Breeze reported, that
+some functions of wxTransformMatrix cannot work because it is not
+known if he matrix has been inverted. Be careful when using it.
 */
-};
 
 // Transform X value from logical to device
+// warning: this function can only be used for this purpose
+// because no rotation is involved when mapping logical to device coordinates
+// mirror and scaling for x and y will be part of the matrix
+// if you have a matrix that is rotated, eg a shape containing a matrix to place
+// it in the logical coordinate system, use TransformPoint
 inline double wxTransformMatrix::TransformX(double x) const
 {
-//     return (m_isIdentity ? x : (x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0]));
-  return 0;
+    //normally like this, but since no rotation is involved (only mirror and scale)
+    //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero
+    //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0]))
+    return (m_isIdentity ? x : (x * m_matrix[0][0] +  m_matrix[2][0]));
 }
 
 // Transform Y value from logical to device
+// warning: this function can only be used for this purpose
+// because no rotation is involved when mapping logical to device coordinates
+// mirror and scaling for x and y will be part of the matrix
+// if you have a matrix that is rotated, eg a shape containing a matrix to place
+// it in the logical coordinate system, use TransformPoint
 inline double wxTransformMatrix::TransformY(double y) const
 {
-//     return (m_isIdentity ? y : (x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1]));
-  return 0;
+    //normally like this, but since no rotation is involved (only mirror and scale)
+    //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero
+    //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1]))
+    return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1]));
 }
 
+
 // Is the matrix the identity matrix?
-// Perhaps there's some kind of optimization we can do to make this
-// a faster operation. E.g. each operation (scale, translate etc.)
-// checks whether it's still the identity matrix and sets a flag.
+// Each operation checks whether the result is still the identity matrix and sets a flag.
 inline bool wxTransformMatrix::IsIdentity1(void) const
 {
-       return
-        (m_matrix[0][0] == 1.0 &&
-         m_matrix[1][1] == 1.0 &&
-         m_matrix[2][2] == 1.0 &&
-         m_matrix[1][0] == 0.0 &&
-         m_matrix[2][0] == 0.0 &&
-         m_matrix[0][1] == 0.0 &&
-         m_matrix[2][1] == 0.0 &&
-         m_matrix[0][2] == 0.0 &&
-         m_matrix[1][2] == 0.0) ;
+    return
+    ( wxIsSameDouble(m_matrix[0][0], 1.0) &&
+      wxIsSameDouble(m_matrix[1][1], 1.0) &&
+      wxIsSameDouble(m_matrix[2][2], 1.0) &&
+      wxIsSameDouble(m_matrix[1][0], 0.0) &&
+      wxIsSameDouble(m_matrix[2][0], 0.0) &&
+      wxIsSameDouble(m_matrix[0][1], 0.0) &&
+      wxIsSameDouble(m_matrix[2][1], 0.0) &&
+      wxIsSameDouble(m_matrix[0][2], 0.0) &&
+      wxIsSameDouble(m_matrix[1][2], 0.0) );
 }
 
 // Calculates the determinant of a 2 x 2 matrix
 inline double wxCalculateDet(double a11, double a21, double a12, double a22)
 {
-       return a11 * a22 - a12 * a21;
+    return a11 * a22 - a12 * a21;
 }
 
-#endif
-       // __MATRIXH__
+#endif // _WX_MATRIXH__