⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxvector.h

📁 希望我上传的这些东西可以对搞编程的程序员有点小小的帮助!谢谢!
💻 H
📖 第 1 页 / 共 3 页
字号:
            return false;
        eM11 = 1.0f / eM11;
        eM22 = 1.0f / eM22;
        break;

    case DX2DXO_SCALE_AND_TRANS:
        {
            if (eM11 == 0.0f || eM22 == 0.0f)
                return false;

            // Our old equation was F = aG + b
            // The inverse is G = F/a - b/a where a is eM11 and b is eDx
            float flOneOverA = 1.0f / eM11;
            eDx = -eDx * flOneOverA;
            eM11 = flOneOverA;

            // Our old equation was F = aG + b
            // The inverse is G = F/a - b/a where a is eM22 and b is eDy

            flOneOverA = 1.0f / eM22;
            eDy = -eDy * flOneOverA;
            eM22 = flOneOverA;
            break;
        }

    case DX2DXO_GENERAL:
    case DX2DXO_GENERAL_AND_TRANS:
        {
            // The inverse of A=  |a b| is | d -c|*(1/Det) where Det is the determinant of A
            //                    |c d|    |-b  a|
            // Det(A) = ad - bc

            // Compute determininant
            float flDet = (eM11 * eM22 -  eM12 * eM21);
            if (flDet == 0.0f)
                return FALSE;

            float flCoef = 1.0f / flDet;

            // Remember old value of eM11
            float flM11Original = eM11;

            eM11 = flCoef * eM22;
            eM12 = -flCoef * eM12;
            eM21 = -flCoef * eM21;
            eM22 = flCoef * flM11Original;

            // If we have a translation; then we need to 
            // compute new values for that translation
            if (eOp == DX2DXO_GENERAL_AND_TRANS)
            {
                // Remember original value of eDx
                float eDxOriginal = eDx;

                eDx = -eM11 * eDx - eM12 * eDy;
                eDy = -eM21 * eDxOriginal - eM22 * eDy;
            }
        }
        break;

    default:
        _ASSERT( 0 );   // invalid operation id
    }

    // We don't need to call DetermineOp here
    // because the op doesn't change when inverted
    // i.e. a scale remains a scale, etc.

    return true;
} /* CDX2DXForm::Invert */

/*** CDXMatrix4x4F ************
*   This class implements basic matrix operation based on a 4x4 array.
*/
//const float g_DXMat4X4Identity[4][4] =
//{
//    { 1.0, 0. , 0. , 0.  },
//    { 0. , 1.0, 0. , 0.  },
//    { 0. , 0. , 1.0, 0.  },
//    { 0. , 0. , 0. , 1.0 }
//};

class CDXMatrix4x4F
{
public:
  /*=== Member Data ===*/
    float m_Coeff[4][4];

  /*=== Methods =======*/
public:
    /*--- Constructors ---*/
    CDXMatrix4x4F() { SetIdentity(); }
    CDXMatrix4x4F( const CDXMatrix4x4F& Other )
        { CopyMemory( (void *)&m_Coeff, (void *)&Other.m_Coeff, sizeof(m_Coeff) ); }
    CDXMatrix4x4F( DX2DXFORM& XForm );

    /*--- operations ---*/
    void ZeroMatrix( void ) { memset( m_Coeff, 0, sizeof( m_Coeff ) ); }
    void SetIdentity( void ) {
        memset( m_Coeff, 0, sizeof( m_Coeff ) );
        m_Coeff[0][0] = m_Coeff[1][1] = m_Coeff[2][2] = m_Coeff[3][3] = 1.0;
    }
    void SetCoefficients( float Coeff[4][4] ) { memcpy( m_Coeff, Coeff, sizeof( m_Coeff )); }
    void GetCoefficients( float Coeff[4][4] ) { memcpy( Coeff, m_Coeff, sizeof( m_Coeff )); }

    //BOOL IsIdentity();
    void Scale( float sx, float sy, float sz );
    void Rotate( float rx, float ry, float rz );
    void Translate( float dx, float dy, float dz );
    BOOL Invert();
    BOOL GetInverse( CDXMatrix4x4F *pIn );
    void Transpose();
    void GetTranspose( CDXMatrix4x4F *pIn );
    void GetAdjoint( CDXMatrix4x4F *pIn );
    HRESULT InitFromSafeArray( SAFEARRAY *psa );
    HRESULT GetSafeArray( SAFEARRAY **ppsa ) const;
    void TransformBounds( DXBNDS& Bnds, DXBNDS& ResultBnds );

    /*--- operators ---*/
    CDXDVec operator*( CDXDVec& v) const;
    CDXCVec operator*( CDXCVec& v) const;
    CDXMatrix4x4F operator*(CDXMatrix4x4F Matrix) const;
    void operator*=(CDXMatrix4x4F Matrix) const;
    void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix);
    void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix);
    void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix);
    BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const;
    BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const;
};

inline CDXMatrix4x4F::CDXMatrix4x4F( DX2DXFORM& XForm )
{
    SetIdentity();
    m_Coeff[0][0] = XForm.eM11;
    m_Coeff[0][1] = XForm.eM12;
    m_Coeff[1][0] = XForm.eM21;
    m_Coeff[1][1] = XForm.eM22;
    m_Coeff[0][3] = XForm.eDx;
    m_Coeff[1][3] = XForm.eDy;
}

// Additional Operations

inline void CDXMatrix4x4F::operator=(const CDXMatrix4x4F srcMatrix)
{
    CopyMemory( (void *)m_Coeff, (const void *)srcMatrix.m_Coeff, sizeof(srcMatrix.m_Coeff) );
} /* CDXMatrix4x4F::operator= */

inline BOOL CDXMatrix4x4F::operator==(const CDXMatrix4x4F otherMatrix) const
{
    return !memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
} /* CDXMatrix4x4F::operator== */

inline BOOL CDXMatrix4x4F::operator!=(const CDXMatrix4x4F otherMatrix) const
{
    return memcmp( (void *)m_Coeff, (const void *)otherMatrix.m_Coeff, sizeof(otherMatrix.m_Coeff) );
} /* CDXMatrix4x4F::operator!= */

inline void CDXMatrix4x4F::operator+=(const CDXMatrix4x4F otherMatrix)
{
    for( int i = 0; i < 4; i++ )
        for( int j = 0; j < 4; j++ )
            m_Coeff[i][j] += otherMatrix.m_Coeff[i][j];
} /* CDXMatrix4x4F::operator+= */

inline void CDXMatrix4x4F::operator-=(const CDXMatrix4x4F otherMatrix) 
{
    for( int i = 0; i < 4; i++ )
        for( int j = 0; j < 4; j++ )
            m_Coeff[i][j] -= otherMatrix.m_Coeff[i][j];
} /* CDXMatrix4x4F::operator-= */

inline CDXDVec CDXMatrix4x4F::operator*(CDXDVec& v) const
{
    CDXDVec t;
    float temp;
    temp = v[0]*m_Coeff[0][0]+v[1]*m_Coeff[1][0]+v[2]*m_Coeff[2][0]+v[3]*m_Coeff[3][0];
    t[0] = (long)((temp < 0) ? temp -= .5 : temp += .5);
    temp = v[0]*m_Coeff[0][1]+v[1]*m_Coeff[1][1]+v[2]*m_Coeff[2][1]+v[3]*m_Coeff[3][1];
    t[1] = (long)((temp < 0) ? temp -= .5 : temp += .5);
    temp = v[0]*m_Coeff[0][2]+v[1]*m_Coeff[1][2]+v[2]*m_Coeff[2][2]+v[3]*m_Coeff[3][2];
    t[2] = (long)((temp < 0) ? temp -= .5 : temp += .5);
    temp = v[0]*m_Coeff[0][3]+v[1]*m_Coeff[1][3]+v[2]*m_Coeff[2][3]+v[3]*m_Coeff[3][3];
    t[3] = (long)((temp < 0) ? temp -= .5 : temp += .5);
    return t;
} /* CDXMatrix4x4F::operator*(DXDVEC) */

inline CDXCVec CDXMatrix4x4F::operator*(CDXCVec& v) const
{
    CDXCVec t;
    t[0] = v[0]*m_Coeff[0][0]+v[1]*m_Coeff[1][0]+v[2]*m_Coeff[2][0]+v[3]*m_Coeff[3][0];
    t[1] = v[0]*m_Coeff[0][1]+v[1]*m_Coeff[1][1]+v[2]*m_Coeff[2][1]+v[3]*m_Coeff[3][1];
    t[2] = v[0]*m_Coeff[0][2]+v[1]*m_Coeff[1][2]+v[2]*m_Coeff[2][2]+v[3]*m_Coeff[3][2];
    t[3] = v[0]*m_Coeff[0][3]+v[1]*m_Coeff[1][3]+v[2]*m_Coeff[2][3]+v[3]*m_Coeff[3][3];
    return t;
} /* CDXMatrix4x4F::operator*(DXCVEC) */

inline CDXMatrix4x4F CDXMatrix4x4F::operator*(CDXMatrix4x4F Mx) const
{
    CDXMatrix4x4F t;
    int i, j;

    for( i = 0; i < 4; i++ )
    {
        for( j = 0; j < 4; j++ )
        {
            t.m_Coeff[i][j] =   m_Coeff[i][0] * Mx.m_Coeff[0][j] + 
                                m_Coeff[i][1] * Mx.m_Coeff[1][j] +
                                m_Coeff[i][2] * Mx.m_Coeff[2][j] +
                                m_Coeff[i][3] * Mx.m_Coeff[3][j];
        }
    }

    return t;
} /* CDXMatrix4x4F::operator*(CDXMatrix4x4F) */
            
inline void CDXMatrix4x4F::operator*=(CDXMatrix4x4F Mx) const
{
    CDXMatrix4x4F t;
    int i, j;

    for( i = 0; i < 4; i++ )
    {
        for( j = 0; j < 4; j++ )
        {
            t.m_Coeff[i][j] =   m_Coeff[i][0] * Mx.m_Coeff[0][j] + 
                                m_Coeff[i][1] * Mx.m_Coeff[1][j] +
                                m_Coeff[i][2] * Mx.m_Coeff[2][j] +
                                m_Coeff[i][3] * Mx.m_Coeff[3][j];
        }
    }

    CopyMemory( (void *)m_Coeff, (void *)t.m_Coeff, sizeof(m_Coeff) );
} /* CDXMatrix4x4F::operator*=(CDXMatrix4x4F) */
            

inline void CDXMatrix4x4F::Scale( float sx, float sy, float sz )
{
    if( sx != 1. )
    {
        m_Coeff[0][0] *= sx;
        m_Coeff[0][1] *= sx;
        m_Coeff[0][2] *= sx;
        m_Coeff[0][3] *= sx;
    }
    if( sy != 1. )
    {
        m_Coeff[1][0] *= sy;
        m_Coeff[1][1] *= sy;
        m_Coeff[1][2] *= sy;
        m_Coeff[1][3] *= sy;
    }
    if( sz != 1. )
    {
        m_Coeff[2][0] *= sz;
        m_Coeff[2][1] *= sz;
        m_Coeff[2][2] *= sz;
        m_Coeff[2][3] *= sz;
    }
} /* CDXMatrix4x4F::Scale */

inline void CDXMatrix4x4F::Translate( float dx, float dy, float dz )
{
    float a, b, c, d;
    a = b = c = d = 0;
    if( dx != 0. )
    {
        a += m_Coeff[0][0]*dx;
        b += m_Coeff[0][1]*dx;
        c += m_Coeff[0][2]*dx;
        d += m_Coeff[0][3]*dx;
    }
    if( dy != 0. )
    {
        a += m_Coeff[1][0]*dy;
        b += m_Coeff[1][1]*dy;
        c += m_Coeff[1][2]*dy;
        d += m_Coeff[1][3]*dy;
    }
    if( dz != 0. )
    {
        a += m_Coeff[2][0]*dz;
        b += m_Coeff[2][1]*dz;
        c += m_Coeff[2][2]*dz;
        d += m_Coeff[2][3]*dz;
    }
    m_Coeff[3][0] += a;
    m_Coeff[3][1] += b;
    m_Coeff[3][2] += c;
    m_Coeff[3][3] += d;
} /* CDXMatrix4x4F::Translate */

inline void CDXMatrix4x4F::Rotate( float rx, float ry, float rz )
{
    const float l_dfCte = (const float)(3.1415926535/180.0);

    float lAngleY = 0.0;
    float lAngleX = 0.0;
    float lAngleZ = 0.0;
    float lCosX = 1.0;
    float lSinX = 0.0;
    float lCosY = 1.0;
    float lSinY = 0.0;
    float lCosZ = 1.0;
    float lSinZ = 0.0;

    // calculate rotation angle sines and cosines
    if( rx != 0 )
    {
        lAngleX = rx * l_dfCte;
        lCosX = (float)cos(lAngleX);
        lSinX = (float)sin(lAngleX);
        if (lCosX > 0.0F && lCosX < 0.0000005F)
        {
            lCosX = .0F;
        }
        if (lSinX > -0.0000005F && lSinX < .0F)
        {
            lSinX = .0F;
        }
    }
    if( ry != 0 )
    {
        lAngleY = ry * l_dfCte;
        lCosY = (float)cos(lAngleY);
        lSinY = (float)sin(lAngleY);
        if (lCosY > 0.0F && lCosY < 0.0000005F)
        {
            lCosY = .0F;
        }
        if (lSinY > -0.0000005F && lSinY < .0F)
        {
            lSinY = .0F;
        }
    }
    if( rz != 0 )
    {
        lAngleZ = rz * l_dfCte;
        lCosZ = (float)cos(lAngleZ);
        lSinZ = (float)sin(lAngleZ);
        if (lCosZ > 0.0F && lCosZ < 0.0000005F)
        {
            lCosZ = .0F;
        }
        if (lSinZ > -0.0000005F && lSinZ < .0F)
        {
            lSinZ = .0F;
        }
    }

    float u, v;
    int i;

    //--- X Rotation
    for( i = 0; i < 4; i++ )
    {
        u = m_Coeff[1][i]; 
        v = m_Coeff[2][i];
        m_Coeff[1][i] = lCosX*u+lSinX*v; 
        m_Coeff[2][i] = -lSinX*u+lCosX*v;
    }

    //--- Y Rotation
    for( i = 0; i < 4; i++ )
    {
        u = m_Coeff[0][i];
        v = m_Coeff[2][i];
        m_Coeff[0][i] = lCosY*u-lSinY*v; 
        m_Coeff[2][i] = lSinY*u+lCosY*v;
    }

    //--- Z Rotation
    for( i = 0; i < 4; i++ )
    {
        u = m_Coeff[0][i];
        v = m_Coeff[1][i];
        m_Coeff[0][i] = lCosZ*u+lSinZ*v; 
        m_Coeff[1][i] = -lSinZ*u+lCosZ*v;
    }
}

/*
inline BOOL CDXMatrix4x4F::IsIdentity()
{
    return  !memcmp( m_Coeff, g_DXMat4X4Identity, sizeof(g_DXMat4X4Identity) );
} /* CDXMatrix4x4F::IsIdentity */


/*
   Uses Gaussian elimination to invert the 4 x 4 non-linear matrix in t and
   return the result in Mx.  The matrix t is destroyed in the process.
*/
inline BOOL CDXMatrix4x4F::Invert()
{
    int i,j,k,Pivot;
    float PValue;
    CDXMatrix4x4F Mx;
    Mx.SetIdentity();

/* Find pivot element.  Use partial pivoting by row */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -