matrix.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// Name: matrix.cpp
// Purpose: wxTransformMatrix class
// Author: Chris Breeze, Julian Smart
// Modified by: Klaas Holwerda
// Created: 01/02/97
// RCS-ID: $Id: matrix.cpp,v 1.15 2005/06/13 12:19:20 ABX Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "matrix.h"
#endif
// 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.
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/math.h"
#endif
#include "wx/matrix.h"
static const double pi = M_PI;
wxTransformMatrix::wxTransformMatrix(void)
{
m_isIdentity = false;
Identity();
}
wxTransformMatrix::wxTransformMatrix(const wxTransformMatrix& mat)
: wxObject()
{
(*this) = mat;
}
double wxTransformMatrix::GetValue(int col, int row) const
{
if (row < 0 || row > 2 || col < 0 || col > 2)
return 0.0;
return m_matrix[col][row];
}
void wxTransformMatrix::SetValue(int col, int row, double value)
{
if (row < 0 || row > 2 || col < 0 || col > 2)
return;
m_matrix[col][row] = value;
m_isIdentity = IsIdentity1();
}
void wxTransformMatrix::operator = (const wxTransformMatrix& mat)
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
m_matrix[i][j] = mat.m_matrix[i][j];
}
}
m_isIdentity = mat.m_isIdentity;
}
bool wxTransformMatrix::operator == (const wxTransformMatrix& mat)
{
if (m_isIdentity && mat.m_isIdentity)
return true;
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
if (m_matrix[i][j] != mat.m_matrix[i][j])
return false;
}
}
return true;
}
bool wxTransformMatrix::operator != (const wxTransformMatrix& mat)
{
return (! ((*this) == mat));
}
double& wxTransformMatrix::operator()(int col, int row)
{
if (row < 0 || row > 2 || col < 0 || col > 2)
return m_matrix[0][0];
return m_matrix[col][row];
}
double wxTransformMatrix::operator()(int col, int row) const
{
if (row < 0 || row > 2 || col < 0 || col > 2)
return 0.0;
return m_matrix[col][row];
}
// Invert matrix
bool wxTransformMatrix::Invert(void)
{
double inverseMatrix[3][3];
// calculate the adjoint
inverseMatrix[0][0] = wxCalculateDet(m_matrix[1][1],m_matrix[2][1],m_matrix[1][2],m_matrix[2][2]);
inverseMatrix[0][1] = -wxCalculateDet(m_matrix[0][1],m_matrix[2][1],m_matrix[0][2],m_matrix[2][2]);
inverseMatrix[0][2] = wxCalculateDet(m_matrix[0][1],m_matrix[1][1],m_matrix[0][2],m_matrix[1][2]);
inverseMatrix[1][0] = -wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][2],m_matrix[2][2]);
inverseMatrix[1][1] = wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][2],m_matrix[2][2]);
inverseMatrix[1][2] = -wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][2],m_matrix[1][2]);
inverseMatrix[2][0] = wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][1],m_matrix[2][1]);
inverseMatrix[2][1] = -wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][1],m_matrix[2][1]);
inverseMatrix[2][2] = wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][1],m_matrix[1][1]);
// now divide by the determinant
double det = m_matrix[0][0] * inverseMatrix[0][0] + m_matrix[0][1] * inverseMatrix[1][0] + m_matrix[0][2] * inverseMatrix[2][0];
if (det != 0.0)
{
inverseMatrix[0][0] /= det; inverseMatrix[1][0] /= det; inverseMatrix[2][0] /= det;
inverseMatrix[0][1] /= det; inverseMatrix[1][1] /= det; inverseMatrix[2][1] /= det;
inverseMatrix[0][2] /= det; inverseMatrix[1][2] /= det; inverseMatrix[2][2] /= det;
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
m_matrix[i][j] = inverseMatrix[i][j];
}
}
m_isIdentity = IsIdentity1();
return true;
}
else
{
return false;
}
}
// Make into identity matrix
bool wxTransformMatrix::Identity(void)
{
m_matrix[0][0] = m_matrix[1][1] = m_matrix[2][2] = 1.0;
m_matrix[1][0] = m_matrix[2][0] = m_matrix[0][1] = m_matrix[2][1] = m_matrix[0][2] = m_matrix[1][2] = 0.0;
m_isIdentity = true;
return true;
}
// Scale by scale (isotropic scaling i.e. the same in x and y):
// | scale 0 0 |
// matrix' = | 0 scale 0 | x matrix
// | 0 0 scale |
//
bool wxTransformMatrix::Scale(double scale)
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
m_matrix[i][j] *= scale;
}
}
m_isIdentity = IsIdentity1();
return true;
}
// scale a matrix in 2D
//
// xs 0 xc(1-xs)
// 0 ys yc(1-ys)
// 0 0 1
//
wxTransformMatrix& wxTransformMatrix::Scale(const double &xs, const double &ys,const double &xc, const double &yc)
{
double r00,r10,r20,r01,r11,r21;
if (m_isIdentity)
{
double tx =xc*(1-xs);
double ty =yc*(1-ys);
r00 = xs;
r10 = 0;
r20 = tx;
r01 = 0;
r11 = ys;
r21 = ty;
}
else if (xc!=0 || yc!=0)
{
double tx =xc*(1-xs);
double ty =yc*(1-ys);
r00 = xs * m_matrix[0][0];
r10 = xs * m_matrix[1][0];
r20 = xs * m_matrix[2][0] + tx;
r01 = ys * m_matrix[0][1];
r11 = ys * m_matrix[1][1];
r21 = ys * m_matrix[2][1] + ty;
}
else
{
r00 = xs * m_matrix[0][0];
r10 = xs * m_matrix[1][0];
r20 = xs * m_matrix[2][0];
r01 = ys * m_matrix[0][1];
r11 = ys * m_matrix[1][1];
r21 = ys * m_matrix[2][1];
}
m_matrix[0][0] = r00;
m_matrix[1][0] = r10;
m_matrix[2][0] = r20;
m_matrix[0][1] = r01;
m_matrix[1][1] = r11;
m_matrix[2][1] = r21;
/* or like this
// first translate to origin O
(*this).Translate(-x_cen, -y_cen);
// now do the scaling
wxTransformMatrix scale;
scale.m_matrix[0][0] = x_fac;
scale.m_matrix[1][1] = y_fac;
scale.m_isIdentity = IsIdentity1();
*this = scale * (*this);
// translate back from origin to x_cen, y_cen
(*this).Translate(x_cen, y_cen);
*/
m_isIdentity = IsIdentity1();
return *this;
}
// mirror a matrix in x, y
//
// -1 0 0 Y-mirror
// 0 -1 0 X-mirror
// 0 0 -1 Z-mirror
wxTransformMatrix& wxTransformMatrix::Mirror(bool x, bool y)
{
wxTransformMatrix temp;
if (x)
{
temp.m_matrix[1][1] = -1;
temp.m_isIdentity=false;
}
if (y)
{
temp.m_matrix[0][0] = -1;
temp.m_isIdentity=false;
}
*this = temp * (*this);
m_isIdentity = IsIdentity1();
return *this;
}
// Translate by dx, dy:
// | 1 0 dx |
// matrix' = | 0 1 dy | x matrix
// | 0 0 1 |
//
bool wxTransformMatrix::Translate(double dx, double dy)
{
int i;
for (i = 0; i < 3; i++)
m_matrix[i][0] += dx * m_matrix[i][2];
for (i = 0; i < 3; i++)
m_matrix[i][1] += dy * m_matrix[i][2];
m_isIdentity = IsIdentity1();
return true;
}
// Rotate clockwise by the given number of degrees:
// | cos sin 0 |
// matrix' = | -sin cos 0 | x matrix
// | 0 0 1 |
bool wxTransformMatrix::Rotate(double degrees)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -