欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

matrix.cpp

A*算法 A*算法 A*算法 A*算法A*算法A*算法
CPP
第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
// 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 + -