📄 dxvector.h
字号:
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 + -