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

📄 dxvector.h

📁 希望我上传的这些东西可以对搞编程的程序员有点小小的帮助!谢谢!
💻 H
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************
* DXVector.h *
*------------*
*   Description:
*       This is the header file for the vector and matrix classes.
*-------------------------------------------------------------------------------
*  Created By: Mike Arnstein                            Date: 04/11/97
*  Copyright (C) 1997 Microsoft Corporation
*  All Rights Reserved
*
*-------------------------------------------------------------------------------
*  Revisions:
*
*******************************************************************************/
#ifndef DXVector_h
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
#define DXVector_h

#ifndef _INC_MATH
#include <math.h>
#endif

#ifndef _INC_CRTDBG
#include <crtdbg.h>
#endif

//=== Constants ====================================================


//=== Class, Enum, Struct and Union Declarations ===================
class CDXMatrix4x4F;

//=== Enumerated Set Definitions ===================================

//=== Function Type Definitions ====================================
float det4x4( CDXMatrix4x4F *pIn );
float det3x3( float a1, float a2, float a3, float b1, float b2, float b3, 
              float c1, float c2, float c3 );
float det2x2( float a, float b, float c, float d );

//=== Class, Struct and Union Definitions ==========================

/*** CDXVec ************
*   This template implements basic vector operations for each of the
*   union types
*/
#define CDXV_C CDXVec<TYPE, eBndType>
#define CDXV_T ((TYPE*)u.D)
#define CDXV_O( OtherVec ) ((TYPE*)OtherVec.u.D)

template<class TYPE, DXBNDTYPE eBndType>
class CDXVec : public DXVEC
{
  /*=== Methods =======*/
  public:
    /*--- Constructors ---*/
    CDXVec() { eType = eBndType; ZeroVector(); }
    CDXVec(BOOL bInit) { eType = eBndType; if (bInit) ZeroVector(); }
    CDXVec( TYPE x, TYPE y, TYPE z, TYPE t )
        { eType = eBndType; CDXV_T[DXB_X] = x; CDXV_T[DXB_Y] = y;
                            CDXV_T[DXB_Z] = z; CDXV_T[DXB_T] = t; }
    CDXVec( const CDXVec& Other ) { memcpy( this, (void *)&Other, sizeof(DXVEC) ); }
    CDXVec( const DXVEC Other ) { memcpy( this, &Other, sizeof(DXVEC) ); }
    operator TYPE *() { return CDXV_T; }
    operator const TYPE *() { return CDXV_T; }

    /*--- operations ---*/
    void ZeroVector( void ) { memset( u.D, 0, sizeof(TYPE) * 4); }

    /*--- operators ---*/
    TYPE&  operator[]( int index ) const { return CDXV_T[index]; }
    TYPE&  operator[]( long index ) const { return CDXV_T[index]; }
    TYPE&  operator[]( USHORT index ) const { return CDXV_T[index]; }
    TYPE&  operator[]( DWORD index ) const { return CDXV_T[index]; }
    CDXV_C operator+(const CDXV_C& v);
    CDXV_C operator-(const CDXV_C& v);
    void   operator=(const CDXV_C& srcVector);
    void   operator+=(const CDXV_C& vOther);
    void   operator-=(const CDXV_C& vOther);
    BOOL   operator==(const CDXV_C& otherVector) const;
    BOOL   operator!=(const CDXV_C& otherVector) const;
};

template<class TYPE, DXBNDTYPE eBndType>
CDXV_C CDXV_C::operator+( const CDXV_C& srcVector )
{
    CDXV_C Result( this );
    CDXV_O( Result )[DXB_X] += CDXV_O( srcVector )[DXB_X];
    CDXV_O( Result )[DXB_Y] += CDXV_O( srcVector )[DXB_Y];
    CDXV_O( Result )[DXB_Z] += CDXV_O( srcVector )[DXB_Z];
    CDXV_O( Result )[DXB_T] += CDXV_O( srcVector )[DXB_T];
    return Result;
} /* CDXVec::operator+ */

template<class TYPE, DXBNDTYPE eBndType>
CDXV_C CDXV_C::operator-( const CDXV_C& srcVector )
{
    CDXV_C Result( this );
    CDXV_O( Result )[DXB_X] -= CDXV_O( srcVector )[DXB_X];
    CDXV_O( Result )[DXB_Y] -= CDXV_O( srcVector )[DXB_Y];
    CDXV_O( Result )[DXB_Z] -= CDXV_O( srcVector )[DXB_Z];
    CDXV_O( Result )[DXB_T] -= CDXV_O( srcVector )[DXB_T];
    return Result;
} /* CDXVec::operator- */

template<class TYPE, DXBNDTYPE eBndType>
void CDXV_C::operator=( const CDXV_C& srcVector )
{
    memcpy( this, &srcVector, sizeof(CDXVec) );
} /* CDXVec::operator= */

template<class TYPE, DXBNDTYPE eBndType>
BOOL CDXV_C::operator==(const CDXV_C& otherVector) const
{
    return !memcmp( this, &otherVector, sizeof(otherVector) );
} /* CDXVec::operator== */

template<class TYPE, DXBNDTYPE eBndType>
BOOL CDXV_C::operator!=(const CDXV_C& otherVector) const
{
    return memcmp( this, &otherVector, sizeof(otherVector) );
} /* CDXVec::operator!= */

template<class TYPE, DXBNDTYPE eBndType>
void CDXV_C::operator+=(const CDXV_C& vOther)
{
    CDXV_T[DXB_X] += CDXV_O( vOther )[DXB_X];
    CDXV_T[DXB_Y] += CDXV_O( vOther )[DXB_Y];
    CDXV_T[DXB_Z] += CDXV_O( vOther )[DXB_Z];
    CDXV_T[DXB_T] += CDXV_O( vOther )[DXB_T];
} /* CDXVec::operator+= */

template<class TYPE, DXBNDTYPE eBndType>
void CDXV_C::operator-=(const CDXVec& vOther)
{
    CDXV_T[DXB_X] -= CDXV_O( vOther )[DXB_X];
    CDXV_T[DXB_Y] -= CDXV_O( vOther )[DXB_Y];
    CDXV_T[DXB_Z] -= CDXV_O( vOther )[DXB_Z];
    CDXV_T[DXB_T] -= CDXV_O( vOther )[DXB_T];
} /* CDXVec::operator-= */

typedef CDXVec<long, DXBT_DISCRETE> CDXDVec;
typedef CDXVec<LONGLONG, DXBT_DISCRETE64> CDXDVec64;
typedef CDXVec<float, DXBT_CONTINUOUS> CDXCVec;
typedef CDXVec<double, DXBT_CONTINUOUS64> CDXCVec64;

/*** CDX2DXForm ************
*   This class implements basic matrix operation based on the GDI XFORM
*   structure.
*/
//const DX2DXFORM g_DX2DXFORMIdentity = { 1., 0., 0., 1., 0., 0., DX2DXO_IDENTITY };

class CDX2DXForm : public DX2DXFORM
{
  /*=== Methods =======*/
public:
    /*--- Constructors ---*/
    CDX2DXForm() { SetIdentity(); }
    CDX2DXForm( const CDX2DXForm& Other ) { memcpy( this, &Other, sizeof(*this) ); }
    CDX2DXForm( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); }

    /*--- methods ---*/
    void DetermineOp( void );
    void Set( const DX2DXFORM& Other ) { memcpy( this, &Other, sizeof(*this) ); DetermineOp(); }
    void ZeroMatrix( void ) { memset( this, 0, sizeof( *this ) ); }
    void SetIdentity( void ) {  
        eM11 = 1.;
        eM12 = 0.;
        eM21 = 0.;
        eM22 = 1.;
        eDx = 0.;
        eDy = 0.;
        eOp = DX2DXO_IDENTITY;
    }
    BOOL IsIdentity() const { return eOp == DX2DXO_IDENTITY; }
    void Scale( float sx, float sy );
    void Rotate( float Rotation );
    void Translate( float dx, float dy );
    BOOL Invert();
    void TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const;
    void TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const;
    void GetMinMaxScales( float& MinScale, float& MaxScale );

    /*--- operators ---*/
    DXFPOINT operator*( const DXFPOINT& v ) const;
    CDX2DXForm operator*( const CDX2DXForm& Other ) const;
};

//=== CDX2DXForm methods ==============================================================
inline void CDX2DXForm::DetermineOp( void )
{
    if( ( eM12 == 0. ) && ( eM21 == 0. ) )
    {
        if( ( eM11 == 1. ) && ( eM22 == 1. ) )
        {
            eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_IDENTITY):(DX2DXO_TRANSLATE);
        }
        else
        {
            eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_SCALE):(DX2DXO_SCALE_AND_TRANS);
        }
    }
    else
    {
        eOp = ( ( eDx == 0 ) && ( eDy == 0 ) )?(DX2DXO_GENERAL):(DX2DXO_GENERAL_AND_TRANS);
    }
} /* CDX2DXForm::DetermineOp */

inline float DXSq( float f ) { return f * f; }

// This function computes the Min and Max scale that a matrix represents.
// In other words, what is the maximum/minimum length that a line of length 1
// could get stretched/shrunk to if the line was transformed by this matrix.
//
// The function uses eigenvalues; and returns two float numbers. Both are
// non-negative; and MaxScale >= MinScale.
// 
inline void CDX2DXForm::GetMinMaxScales( float& MinScale, float& MaxScale )
{
    if( ( eM12 == 0. ) && ( eM21 == 0. ) )
    {
        // Let MinScale = abs(eM11)
        if (eM11 < 0)
            MinScale = -eM11;
        else
            MinScale = eM11;

        // Let MaxScale = abs(eM22)
        if (eM22 < 0)
            MaxScale = -eM22;
        else
            MaxScale = eM22;

        // Swap Min/Max if necessary
        if (MinScale > MaxScale)
        {
            float flTemp = MinScale;
            MinScale = MaxScale;
            MaxScale = flTemp;
        }
    }
    else
    {
        float t1 = DXSq(eM11) + DXSq(eM12) + DXSq(eM21) + DXSq(eM22);
        if( t1 == 0. )
        {
            MinScale = MaxScale = 0;
        }
        else
        {
            float t2 = (float)sqrt( (DXSq(eM12 + eM21) + DXSq(eM11 - eM22)) *
                                    (DXSq(eM12 - eM21) + DXSq(eM11 + eM22)) );

            // Due to floating point error; t1 may end up less than t2;
            // but that would mean that the min scale was small (relative
            // to max scale)
            if (t1 <= t2)
                MinScale = 0;
            else
                MinScale = (float)sqrt( (t1 - t2) * .5f );

            MaxScale = (float)sqrt( (t1 + t2) * .5f );
        }
    }
} /* CDX2DXForm::GetMinMaxScales */

inline void CDX2DXForm::Rotate( float Rotation )
{
    double Angle = Rotation * (3.1415926535/180.0);
    float CosZ   = (float)cos( Angle );
    float SinZ   = (float)sin( Angle );
    if (CosZ > 0.0F && CosZ < 0.0000005F)
    {
        CosZ = .0F;
    }
    if (SinZ > -0.0000005F && SinZ < .0F)
    {
        SinZ = .0F;
    }

    float M11 = ( CosZ * eM11 ) + ( SinZ * eM21 ); 
    float M21 = (-SinZ * eM11 ) + ( CosZ * eM21 );
    float M12 = ( CosZ * eM12 ) + ( SinZ * eM22 ); 
    float M22 = (-SinZ * eM12 ) + ( CosZ * eM22 );
    eM11 = M11; eM21 = M21; eM12 = M12; eM22 = M22;
    DetermineOp();
} /* CDX2DXForm::Rotate */

inline void CDX2DXForm::Scale( float sx, float sy )
{
    eM11 *= sx;
    eM12 *= sx;
    eDx  *= sx;
    eM21 *= sy;
    eM22 *= sy;
    eDy  *= sy;
    DetermineOp();
} /* CDX2DXForm::Scale */

inline void CDX2DXForm::Translate( float dx, float dy )
{
    eDx += dx;
    eDy += dy;
    DetermineOp();
} /* CDX2DXForm::Translate */

inline void CDX2DXForm::TransformBounds( const DXBNDS& Bnds, DXBNDS& ResultBnds ) const
{
    ResultBnds = Bnds;
    if( eOp != DX2DXO_IDENTITY )
    {
        ResultBnds.u.D[DXB_X].Min = (long)(( eM11 * Bnds.u.D[DXB_X].Min ) + ( eM12 * Bnds.u.D[DXB_Y].Min ) + eDx);
        ResultBnds.u.D[DXB_X].Max = (long)(( eM11 * Bnds.u.D[DXB_X].Max ) + ( eM12 * Bnds.u.D[DXB_Y].Max ) + eDx);
        ResultBnds.u.D[DXB_Y].Min = (long)(( eM21 * Bnds.u.D[DXB_X].Min ) + ( eM22 * Bnds.u.D[DXB_Y].Min ) + eDy);
        ResultBnds.u.D[DXB_Y].Max = (long)(( eM21 * Bnds.u.D[DXB_X].Max ) + ( eM22 * Bnds.u.D[DXB_Y].Max ) + eDy);
    }
} /* CDX2DXForm::TransformBounds */

inline void CDX2DXForm::TransformPoints( const DXFPOINT InPnts[], DXFPOINT OutPnts[], ULONG ulCount ) const
{
    ULONG i;
    switch( eOp )
    {
      case DX2DXO_IDENTITY:
        memcpy( OutPnts, InPnts, ulCount * sizeof( DXFPOINT ) );
        break;
      case DX2DXO_TRANSLATE:
        for( i = 0; i < ulCount; ++i )
        {
            OutPnts[i].x = InPnts[i].x + eDx;
            OutPnts[i].y = InPnts[i].y + eDy;
        }
        break;
      case DX2DXO_SCALE:
        for( i = 0; i < ulCount; ++i )
        {
            OutPnts[i].x = InPnts[i].x * eM11;
            OutPnts[i].y = InPnts[i].y * eM22;
        }
        break;
      case DX2DXO_SCALE_AND_TRANS:
        for( i = 0; i < ulCount; ++i )
        {
            OutPnts[i].x = (InPnts[i].x * eM11) + eDx;
            OutPnts[i].y = (InPnts[i].y * eM22) + eDy;
        }
        break;
      case DX2DXO_GENERAL:
        for( i = 0; i < ulCount; ++i )
        {
            OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 );
            OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 );
        }
        break;
      case DX2DXO_GENERAL_AND_TRANS:
        for( i = 0; i < ulCount; ++i )
        {
            OutPnts[i].x = ( InPnts[i].x * eM11 ) + ( InPnts[i].y * eM12 ) + eDx;
            OutPnts[i].y = ( InPnts[i].x * eM21 ) + ( InPnts[i].y * eM22 ) + eDy;
        }
        break;
      default:
        _ASSERT( 0 );   // invalid operation id
    }
} /* CDX2DXForm::TransformPoints */

inline DXFPOINT CDX2DXForm::operator*( const DXFPOINT& v ) const
{
    DXFPOINT NewPnt;
    NewPnt.x = ( v.x * eM11 ) + ( v.y * eM12 ) + eDx;
    NewPnt.y = ( v.x * eM21 ) + ( v.y * eM22 ) + eDy;
    return NewPnt;
} /* CDX2DXForm::operator* */

inline CDX2DXForm CDX2DXForm::operator*( const CDX2DXForm& Other ) const
{
    DX2DXFORM x;
    x.eM11 = ( eM11 * Other.eM11 ) + ( eM12 * Other.eM21 );
    x.eM12 = ( eM11 * Other.eM12 ) + ( eM12 * Other.eM22 );
    x.eDx  = ( eM11 * Other.eDx  ) + ( eM12 * Other.eDy  ) + eDx;

    x.eM21 = ( eM21 * Other.eM11 ) + ( eM22 * Other.eM21 );
    x.eM22 = ( eM21 * Other.eM12 ) + ( eM22 * Other.eM22 );
    x.eDy  = ( eM21 * Other.eDx  ) + ( eM22 * Other.eDy  ) + eDy;
    return x;
} /* CDX2DXForm::operator*= */

inline BOOL CDX2DXForm::Invert()
{
    switch( eOp )
    {
    case DX2DXO_IDENTITY:
        break;
    case DX2DXO_TRANSLATE:
        eDx = -eDx;
        eDy = -eDy;
        break;
    case DX2DXO_SCALE:

        if (eM11 == 0.0 || eM22 == 0.0)

⌨️ 快捷键说明

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