예제 #1
0
void rms::ComputeAlignAxisMatrix( const Vector3<Real> & vInitial,
								  const Vector3<Real> & vAlignWith, Matrix3<Real> & matrix )
{
	// compute cosine of angle between vectors
	Real axisDot = vAlignWith.Dot( vInitial );

	// compute rotation axis
	Vector3<Real> axisCross( vInitial.Cross( vAlignWith ) );

	// apply rotation if necessary
	if (axisCross.SquaredLength() > Wml::Math<Real>::EPSILON) {

		// compute normalized axis and angle, then create rotation around axis
		axisCross.Normalize();
		Real fAngle = Math<Real>::ACos( axisDot / vAlignWith.Length() );
		matrix.FromAxisAngle( axisCross, fAngle );

	} else if (axisDot < (Real)0) {

		// find some perpendicular vectors
		Wml::Vector3<Real> vPerp1, vPerp2;
		ComputePerpVectors( vInitial, vPerp1, vPerp2 );

		matrix.FromAxisAngle( vPerp1, (Real)180 * Math<Real>::DEG_TO_RAD );
	} else {
		matrix = Matrix3<Real>::IDENTITY;
	}
}
예제 #2
0
void rms::ComputeAlignZAxisMatrix( const Vector3<Real> & vAlignWith,
								  Matrix3<Real> & matrix, bool bInvert )
{
	// compute cosine of angle between vectors
	Real axisDot = vAlignWith.Dot( Vector3<Real>::UNIT_Z );

	// compute rotation axis
	Vector3<Real> axisCross( Vector3<Real>::UNIT_Z.Cross( vAlignWith ) );

	Real fInverter = (bInvert) ? (Real)-1 : (Real)1;

	// apply rotation if necessary
	if (axisCross.SquaredLength() > Wml::Math<Real>::EPSILON) {

		// compute normalized axis and angle, then create rotation around axis
		axisCross.Normalize();
		Real fAngle = Math<Real>::ACos( axisDot / vAlignWith.Length() );
		matrix.FromAxisAngle( axisCross, fAngle * fInverter );

	} else if (axisDot < (Real)0) {
		matrix.FromAxisAngle( Vector3<Real>::UNIT_X, (Real)180 * Math<Real>::DEG_TO_RAD * fInverter );
	} else {
		matrix = Matrix3<Real>::IDENTITY;
	}
}
예제 #3
0
//----------------------------------------------------------------------------
static void MinimalBoxForAngles (int iQuantity, const Vector3* akPoint,
    Real afAngle[3], Box3& rkBox)
{
    Real fCos0 = Math::Cos(afAngle[0]);
    Real fSin0 = Math::Sin(afAngle[0]);
    Real fCos1 = Math::Cos(afAngle[1]);
    Real fSin1 = Math::Sin(afAngle[1]);
    Vector3 kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3 kRot;
    kRot.FromAxisAngle(kAxis,afAngle[2]);

    Vector3 kMin = akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        Vector3 kTest = akPoint[i]*kRot;

        if ( kTest.x < kMin.x )
            kMin.x = kTest.x;
        else if ( kTest.x > kMax.x )
            kMax.x = kTest.x;

        if ( kTest.y < kMin.y )
            kMin.y = kTest.y;
        else if ( kTest.y > kMax.y )
            kMax.y = kTest.y;

        if ( kTest.z < kMin.z )
            kMin.z = kTest.z;
        else if ( kTest.z > kMax.z )
            kMax.z = kTest.z;
    }

    Vector3 kMid = 0.5f*(kMax + kMin);
    Vector3 kRng = 0.5f*(kMax - kMin);

    rkBox.Center() = kRot*kMid;
    rkBox.Axis(0) = kRot.GetColumn(0);
    rkBox.Axis(1) = kRot.GetColumn(1);
    rkBox.Axis(2) = kRot.GetColumn(2);
    rkBox.Extent(0) = kRng.x;
    rkBox.Extent(1) = kRng.y;
    rkBox.Extent(2) = kRng.z;
}
예제 #4
0
//----------------------------------------------------------------------------
static Real Volume (const Real* afAngle, void* pvUserData)
{
    int iQuantity = ((PointArray*)pvUserData)->m_iQuantity;
    const Vector3* akPoint = ((PointArray*)pvUserData)->m_akPoint;

    Real fCos0 = Math::Cos(afAngle[0]);
    Real fSin0 = Math::Sin(afAngle[0]);
    Real fCos1 = Math::Cos(afAngle[1]);
    Real fSin1 = Math::Sin(afAngle[1]);
    Vector3 kAxis(fCos0*fSin1,fSin0*fSin1,fCos1);
    Matrix3 kRot;
    kRot.FromAxisAngle(kAxis,afAngle[2]);

    Vector3 kMin = akPoint[0]*kRot, kMax = kMin;
    for (int i = 1; i < iQuantity; i++)
    {
        Vector3 kTest = akPoint[i]*kRot;

        if ( kTest.x < kMin.x )
            kMin.x = kTest.x;
        else if ( kTest.x > kMax.x )
            kMax.x = kTest.x;

        if ( kTest.y < kMin.y )
            kMin.y = kTest.y;
        else if ( kTest.y > kMax.y )
            kMax.y = kTest.y;

        if ( kTest.z < kMin.z )
            kMin.z = kTest.z;
        else if ( kTest.z > kMax.z )
            kMax.z = kTest.z;
    }

    Real fVolume = (kMax.x-kMin.x)*(kMax.y-kMin.y)*(kMax.z-kMin.z);
    return fVolume;
}
//---------------------------------------------------------------------------
long FAR PASCAL 
WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static Vector3 s_kEye;
    static QuadricSurface::ConvexPolyhedron s_kPoly;
    static int s_iSteps = 0;
    static Matrix3 s_kRot;
    Matrix3 kIncr;

    switch ( message ) 
    {
    case WM_CREATE:
    {
        CreatePoly(s_kPoly);
        QuadricSurface::TessellateSphere(s_iSteps,s_kPoly);

        // initial camera orientation and eye point
        s_kRot.FromAxisAngle(Vector3::UNIT_Z,0.0f);
        s_kEye = 2.0f*s_kRot.GetColumn(2);

        return 0;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd,&ps);
        DrawPolyhedron(hDC,s_kEye,s_kRot,s_kPoly);
        EndPaint(hWnd,&ps);
        return 0;
    }
    case WM_KEYDOWN:
    {
        switch ( wParam )
        {
        case VK_LEFT:
        {
            // rotate camera about its 'up' vector
            kIncr.FromAxisAngle(s_kRot.GetColumn(1),0.1f);
            s_kRot = kIncr*s_kRot;
            s_kEye = 2.0f*s_kRot.GetColumn(2);
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        case VK_RIGHT:
        {
            // rotate camera about its 'up' vector
            kIncr.FromAxisAngle(s_kRot.GetColumn(1),-0.1f);
            s_kRot = kIncr*s_kRot;
            s_kEye = 2.0f*s_kRot.GetColumn(2);
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        case VK_UP:
        {
            // rotate camera about its 'right' vector
            kIncr.FromAxisAngle(s_kRot.GetColumn(0),-0.1f);
            s_kRot = kIncr*s_kRot;
            s_kEye = 2.0f*s_kRot.GetColumn(2);
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        case VK_DOWN:
        {
            // rotate camera about its 'right' vector
            kIncr.FromAxisAngle(s_kRot.GetColumn(0),0.1f);
            s_kRot = kIncr*s_kRot;
            s_kEye = 2.0f*s_kRot.GetColumn(2);
            InvalidateRect(hWnd,NULL,TRUE);
            break;
        }
        }
        return 0;
    }
    case WM_CHAR:
    {
        switch ( wParam )
        {
            case '+':
            case '=':
            {
                s_iSteps++;
                QuadricSurface::DeletePolyhedron(s_kPoly);
                CreatePoly(s_kPoly);
                QuadricSurface::TessellateSphere(s_iSteps,s_kPoly);
                InvalidateRect(hWnd,NULL,TRUE);
                break;
            }
            case '-':
            case '_':
            {
                if ( s_iSteps >= 1 )
                {
                    s_iSteps--;
                    QuadricSurface::DeletePolyhedron(s_kPoly);
                    CreatePoly(s_kPoly);
                    QuadricSurface::TessellateSphere(s_iSteps,s_kPoly);
                    InvalidateRect(hWnd,NULL,TRUE);
                }
                break;
            }
            case 'q':
            case 'Q':
            case VK_ESCAPE:
            {
                PostMessage(hWnd,WM_DESTROY,0,0);
                break;
            }
        }
        return 0;
    }
    case WM_DESTROY:
    {
        QuadricSurface::DeletePolyhedron(s_kPoly);
        PostQuitMessage(0);
        return 0;
    }
    }
	return DefWindowProc(hWnd,message,wParam,lParam);
}