1998-05-20 14:01:55 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: matrix.h
|
|
|
|
// Purpose: wxTransformMatrix class. NOT YET USED
|
2003-03-17 10:34:04 +00:00
|
|
|
// Author: Chris Breeze, Julian Smart
|
2000-11-24 12:40:19 +00:00
|
|
|
// Modified by: Klaas Holwerda
|
1998-05-20 14:01:55 +00:00
|
|
|
// Created: 01/02/97
|
|
|
|
// RCS-ID: $Id$
|
2003-03-17 10:34:04 +00:00
|
|
|
// Copyright: (c) Julian Smart, Chris Breeze
|
2000-11-24 12:40:19 +00:00
|
|
|
// Licence: wxWindows licence
|
1998-05-20 14:01:55 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
1998-08-15 00:23:28 +00:00
|
|
|
#ifndef _WX_MATRIXH__
|
|
|
|
#define _WX_MATRIXH__
|
1998-05-20 14:01:55 +00:00
|
|
|
|
2003-08-09 12:38:21 +00:00
|
|
|
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
1998-05-20 14:01:55 +00:00
|
|
|
#pragma interface "matrix.h"
|
|
|
|
#endif
|
|
|
|
|
2000-11-24 12:40:19 +00:00
|
|
|
//! headerfiles="matrix.h wx/object.h"
|
1998-05-20 14:01:55 +00:00
|
|
|
#include "wx/object.h"
|
|
|
|
|
2000-11-24 12:40:19 +00:00
|
|
|
//! codefiles="matrix.cpp"
|
|
|
|
|
1998-05-20 14:01:55 +00:00
|
|
|
// 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.
|
|
|
|
|
2003-06-30 13:11:51 +00:00
|
|
|
//:definition
|
2000-11-24 12:40:19 +00:00
|
|
|
// A 3x3 matrix to do 2D transformations.
|
2003-06-30 13:11:51 +00:00
|
|
|
// It can be used to map data to window coordinates,
|
|
|
|
// and also for manipulating your own data.
|
2000-11-24 12:40:19 +00:00
|
|
|
// 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.
|
1998-05-20 14:01:55 +00:00
|
|
|
class WXDLLEXPORT wxTransformMatrix: public wxObject
|
|
|
|
{
|
|
|
|
public:
|
2000-11-24 12:40:19 +00:00
|
|
|
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);
|
|
|
|
bool operator != (const wxTransformMatrix& mat);
|
|
|
|
|
|
|
|
//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 |
|
2000-11-27 19:59:25 +00:00
|
|
|
wxTransformMatrix& Mirror(bool x=TRUE, bool y=FALSE);
|
2000-11-24 12:40:19 +00:00
|
|
|
// 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);
|
1998-05-20 14:01:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
public:
|
2000-11-24 12:40:19 +00:00
|
|
|
double m_matrix[3][3];
|
|
|
|
bool m_isIdentity;
|
1998-05-20 14:01:55 +00:00
|
|
|
};
|
|
|
|
|
1998-07-24 19:05:25 +00:00
|
|
|
|
|
|
|
/*
|
2000-11-24 12:40:19 +00:00
|
|
|
Chris Breeze reported, that
|
1998-07-24 19:05:25 +00:00
|
|
|
some functions of wxTransformMatrix cannot work because it is not
|
|
|
|
known if he matrix has been inverted. Be careful when using it.
|
2000-11-24 12:40:19 +00:00
|
|
|
*/
|
1998-07-24 19:05:25 +00:00
|
|
|
|
1998-05-20 14:01:55 +00:00
|
|
|
// Transform X value from logical to device
|
2000-11-24 12:40:19 +00:00
|
|
|
// 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
|
1998-05-20 14:01:55 +00:00
|
|
|
inline double wxTransformMatrix::TransformX(double x) const
|
|
|
|
{
|
2000-11-24 12:40:19 +00:00
|
|
|
//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]));
|
1998-05-20 14:01:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Transform Y value from logical to device
|
2000-11-24 12:40:19 +00:00
|
|
|
// 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
|
1998-05-20 14:01:55 +00:00
|
|
|
inline double wxTransformMatrix::TransformY(double y) const
|
|
|
|
{
|
2000-11-24 12:40:19 +00:00
|
|
|
//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]));
|
1998-05-20 14:01:55 +00:00
|
|
|
}
|
2000-11-24 12:40:19 +00:00
|
|
|
|
1998-05-20 14:01:55 +00:00
|
|
|
|
|
|
|
// Is the matrix the identity matrix?
|
2000-11-24 12:40:19 +00:00
|
|
|
// Each operation checks whether the result is still the identity matrix and sets a flag.
|
1998-05-20 14:01:55 +00:00
|
|
|
inline bool wxTransformMatrix::IsIdentity1(void) const
|
|
|
|
{
|
2000-11-24 12:40:19 +00:00
|
|
|
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) ;
|
1998-05-20 14:01:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Calculates the determinant of a 2 x 2 matrix
|
|
|
|
inline double wxCalculateDet(double a11, double a21, double a12, double a22)
|
|
|
|
{
|
2000-11-24 12:40:19 +00:00
|
|
|
return a11 * a22 - a12 * a21;
|
1998-05-20 14:01:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2000-11-24 12:40:19 +00:00
|
|
|
// _WX_MATRIXH__
|