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

📄 testdistance.cpp

📁 《3D游戏引擎设计》的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License.html/free.pdf

#include <MgcCore.pkg>
#include <MgcDistance.pkg>

#define RAND (2.0f*rand()/MgcReal(RAND_MAX)-1)

//----------------------------------------------------------------------------
void TestDistVec3Lin3 ()
{
}
//----------------------------------------------------------------------------
void TestDistVec3Tri3 ()
{
    ofstream ostr("data.txt");

    MgcTriangle3 kTri;
    MgcVector3 kP, kQ, kDiff;
    MgcReal fS, fT, fS0, fT0, fMin0, fMin1, fDist;
    MgcReal fMaxDiff = 0.0;

    for (int i = 0; i < 128; i++)
    {
        kTri.Origin() = MgcVector3(RAND,RAND,RAND);
        kTri.Edge0() = MgcVector3(RAND,RAND,RAND);
        kTri.Edge1() = MgcVector3(RAND,RAND,RAND);
        kP = MgcVector3(RAND,RAND,RAND);

        fMin0 = MgcMath::INFINITY;
        int iMax = 128;
        for (int iY = 0; iY <= iMax; iY++)
        {
            fS0 = iY/MgcReal(iMax);
            for (int iX = 0; iX+iY <= iMax; iX++)
            {
                fT0 = iX/MgcReal(iMax);
                kQ = kTri.Origin()+fS0*kTri.Edge0()+fT0*kTri.Edge1();
                kDiff = kP-kQ;
                fDist = kDiff.Length();
                if ( fDist < fMin0 )
                {
                    fMin0 = fDist;
                    fS = fS0;
                    fT = fT0;
                }
            }
        }
        ostr << "sampled = " << fS << ' ' << fT << ' ' << fMin0 << endl;

        fMin1 = MgcDistance(kP,kTri,&fS,&fT);
        ostr << "analytic = " << fS << ' ' << fT << ' ' << fMin1 << endl;

        ostr << "diff = " << fMin1-fMin0 << endl;

        if ( fMin1-fMin0 > fMaxDiff )
            fMaxDiff = fMin1-fMin0;

        ostr << endl;
    }
    ostr << "max diff = " << fMaxDiff << endl;
}
//----------------------------------------------------------------------------
void TestDistVec3Pgm3 ()
{
    ofstream ostr("data.txt");
    MgcParallelogram3 kPgm;
    MgcVector3 kP, kQ, kDiff;
    MgcReal fS, fT, fS0, fT0, fMin0, fMin1, fDist;
    MgcReal fMaxDiff = 0.0;

    for (int i = 0; i < 128; i++)
    {
        kPgm.Origin() = MgcVector3(RAND,RAND,RAND);
        kPgm.Edge0() = MgcVector3(RAND,RAND,RAND);
        kPgm.Edge1() = MgcVector3(RAND,RAND,RAND);
        kP = MgcVector3(RAND,RAND,RAND);

        fMin0 = MgcMath::INFINITY;
        int iMax = 128;
        for (int iY = 0; iY <= iMax; iY++)
        {
            fS0 = iY/MgcReal(iMax);
            for (int iX = 0; iX <= iMax; iX++)
            {
                fT0 = iX/MgcReal(iMax);
                kQ = kPgm.Origin()+fS0*kPgm.Edge0()+fT0*kPgm.Edge1();
                kDiff = kP-kQ;
                fDist = kDiff.Length();
                if ( fDist < fMin0 )
                {
                    fMin0 = fDist;
                    fS = fS0;
                    fT = fT0;
                }
            }
        }
        ostr << "sampled = " << fS << ' ' << fT << ' ' << fMin0 << endl;

        fMin1 = MgcDistance(kP,kPgm,&fS,&fT);
        ostr << "analytic = " << fS << ' ' << fT << ' ' << fMin1 << endl;
        ostr << "diff = " << fMin1-fMin0 << endl;
        if ( fMin1-fMin0 > fMaxDiff )
            fMaxDiff = fMin1-fMin0;
        ostr << endl;
    }

    ostr << "max diff = " << fMaxDiff << endl;
    ostr << endl;
}
//----------------------------------------------------------------------------
void TestDistVec3Rct3 ()
{
    ofstream ostr("data.txt");
    MgcRectangle3 kRct;
    MgcVector3 kP, kQ, kDiff;
    MgcReal fS, fT, fS0, fT0, fMin0, fMin1, fDist;
    MgcReal fMaxDiff = 0.0;

    for (int i = 0; i < 128; i++)
    {
        kRct.Origin() = MgcVector3(RAND,RAND,RAND);
        kRct.Edge0() = MgcVector3(RAND,RAND,RAND);
        MgcVector3::GenerateOrthonormalBasis(kP,kQ,kRct.Edge0(),false);
        kRct.Edge1() = kQ;
        kP = MgcVector3(RAND,RAND,RAND);

        fMin0 = MgcMath::INFINITY;
        int iMax = 128;
        for (int iY = 0; iY <= iMax; iY++)
        {
            fS0 = iY/MgcReal(iMax);
            for (int iX = 0; iX <= iMax; iX++)
            {
                fT0 = iX/MgcReal(iMax);
                kQ = kRct.Origin()+fS0*kRct.Edge0()+fT0*kRct.Edge1();
                kDiff = kP-kQ;
                fDist = kDiff.Length();
                if ( fDist < fMin0 )
                {
                    fMin0 = fDist;
                    fS = fS0;
                    fT = fT0;
                }
            }
        }
        ostr << "sampled = " << fS << ' ' << fT << ' ' << fMin0 << endl;

        fMin1 = MgcDistance(kP,kRct,&fS,&fT);
        ostr << "analytic = " << fS << ' ' << fT << ' ' << fMin1 << endl;
        ostr << "diff = " << fMin1-fMin0 << endl;
        if ( fMin1-fMin0 > fMaxDiff )
            fMaxDiff = fMin1-fMin0;
        ostr << endl;
    }

    ostr << "max diff = " << fMaxDiff << endl;
    ostr << endl;
}
//----------------------------------------------------------------------------
void TestDistVec3Cir3 ()
{
    ofstream ostr("data.txt");

    MgcCircle3 kCircle;
    MgcVector3 kP;
    MgcReal fMin0, fMin1, fDistance, fMinAngle;
    MgcReal fMaxDiff = 0.0;

    const int iMax = 32;
    for (int i = 0; i < iMax; i++)
    {
        kCircle.Radius() = 1.01 + RAND;  // >= 0.01
        kCircle.Center() = MgcVector3(RAND,RAND,RAND);
        kCircle.N() = MgcVector3(RAND,RAND,RAND);
        kCircle.N().Unitize();

        if ( MgcMath::Abs(kCircle.N().x) > MgcMath::Abs(kCircle.N().y)
        &&   MgcMath::Abs(kCircle.N().x) > MgcMath::Abs(kCircle.N().z) )
        {
            kCircle.U().x = +kCircle.N().y;
            kCircle.U().y = -kCircle.N().x;
            kCircle.U().z = 0.0;
        }
        else
        {
            kCircle.U().x = 0.0;
            kCircle.U().y = +kCircle.N().z;
            kCircle.U().z = -kCircle.N().y;
        }
        kCircle.U().Unitize();
        kCircle.V() = kCircle.N().Cross(kCircle.U());

        kP = MgcVector3(RAND,RAND,RAND);

        // sample kCircle to compute minimum fDistance
        fMin0 = MgcMath::INFINITY;
        const int iAMax = 128, iSMax = 128;
        MgcReal fAngle, fCos, fSin;
        MgcVector3 kK, kDiff;
        for (int iA = -iAMax; iA <= iAMax; iA++)
        {
            fAngle = MgcMath::PI*MgcReal(iA)/MgcReal(iAMax);
            fCos = MgcMath::Cos(fAngle);
            fSin = MgcMath::Sin(fAngle);
            kK = kCircle.Center() + kCircle.Radius()*(fCos*kCircle.U() +
                fSin*kCircle.V());
            kDiff = kP-kK;
            fDistance = kDiff.Length();
            if ( fDistance < fMin0 )
            {
                fMin0 = fDistance;
                fMinAngle = fAngle;
            }
        }

        ostr << "sampled:   angle = " << fMinAngle << " min = " << fMin0
             << endl;

        // analytic solution
        fMin1 = MgcDistance(kP,kCircle,&kK);
        kDiff = (1.0f/kCircle.Radius())*(kK - kCircle.Center());
        fCos = kDiff.Dot(kCircle.U());
        fSin = kDiff.Dot(kCircle.V());
        fMinAngle = MgcMath::ATan2(fSin,fCos);

        ostr << "analytic:  angle = " << fMinAngle << " min = " << fMin1
             << endl;

        MgcReal fCompDiff = fMin1-fMin0;
        ostr << "diff = " << fCompDiff << endl;
        if ( fCompDiff > fMaxDiff )
            fMaxDiff = fCompDiff;

        ostr << endl;
    }

    ostr << "max diff = " << fMaxDiff << endl;
}
//----------------------------------------------------------------------------
void TestDistVec2Qdr2 ()
{
    MgcReal afQuad[6] =
    {
        -1.0,  // 1-term
         0.0,  // x-term
         0.0,  // y-term
         1.0,  // x^2-term
         1.0,  // y^2-term
         0.0   // xy-term
    };

    MgcVector2 kPoint(2.0,2.0);

    MgcVector2 kClosest0;
    MgcReal fDist0 = MgcDistance(kPoint,afQuad,kClosest0);

    MgcEllipseStandard kEllipse;
    kEllipse.Extent(0) = 1.0;
    kEllipse.Extent(1) = 1.0;
    MgcVector2 kClosest1;
    MgcReal fDist1 = MgcDistance(kEllipse,kPoint,kClosest1);
}
//----------------------------------------------------------------------------
void TestDistVec3Qdr3 ()
{
    MgcReal afQuad[10] =
    {
        -1.0,  // 1-term
         0.0,  // x-term
         0.0,  // y-term
         0.0,  // z-term
         1.0,  // x^2-term
         1.0/4.0,  // y^2-term
         1.0/9.0,  // z^2-term
         0.0,  // xy-term
         0.0,  // xz-term
         0.0,  // yz-term
    };

    MgcVector3 kPoint(2.0,2.0,2.0);

    MgcVector3 kClosest0;
    MgcReal fDist0 = MgcDistance(kPoint,afQuad,kClosest0);

    MgcEllipsoidStandard kEllipsoid;
    kEllipsoid.Extent(0) = 1.0;
    kEllipsoid.Extent(1) = 2.0;
    kEllipsoid.Extent(2) = 3.0;
    MgcVector3 kClosest1;
    MgcReal fDist1 = MgcDistance(kEllipsoid,kPoint,kClosest1);
}
//----------------------------------------------------------------------------
void TestDistSeg3Seg3 ()
{
    ofstream ostr("data.txt");

    MgcSegment3 rkSeg0, rkSeg1;
    MgcVector3 kP0, kP1, kDiff;
    MgcReal fS, fT, fS0, fT0, fMin0, fMin1, fDist;
    MgcReal fMaxDiff = 0.0;

    for (int i = 0; i < 128; i++)
    {
        rkSeg0.Origin() = MgcVector3(RAND,RAND,RAND);
        rkSeg0.Direction() = MgcVector3(RAND,RAND,RAND);
        rkSeg1.Origin() = MgcVector3(RAND,RAND,RAND);

        if ( i % 2 )
        {
            // non-parallel line segments
            rkSeg1.Direction() = MgcVector3(RAND,RAND,RAND);
        }
        else
        {
            // parallel line segments
            rkSeg1.Direction() = RAND*rkSeg0.Direction();
        }

        fMin0 = MgcMath::INFINITY;
        int iYMax = 128, iXMax = 128;
        for (int iY = 0; iY < iYMax; iY++)
        {
            fS0 = iY/MgcReal(iYMax-1);
            kP0 = rkSeg0.Origin()+fS0*rkSeg0.Direction();
            for (int iX = 0; iX < iXMax; iX++)
            {
                fT0 = iX/MgcReal(iXMax-1);
                kP1 = rkSeg1.Origin()+fT0*rkSeg1.Direction();
                kDiff = kP1-kP0;
                fDist = kDiff.Length();
                if ( fDist < fMin0 )
                {
                    fMin0 = fDist;
                    fS = fS0;
                    fT = fT0;
                }
            }
        }
        ostr << "sampled = " << fS << ' ' << fT << ' ' << fMin0 << endl;

        fMin1 = MgcDistance(rkSeg0,rkSeg1,&fS,&fT);
        ostr << "analytic = " << fS << ' ' << fT << ' ' << fMin1 << endl;

        MgcReal fCompDiff = fMin1-fMin0;
        ostr << "diff = " << fCompDiff << endl;
        if ( fCompDiff > fMaxDiff )
            fMaxDiff = fCompDiff;

        ostr << endl;
    }
    ostr << "max diff = " << fMaxDiff << endl;
}
//----------------------------------------------------------------------------
void TestDistLin3Seg3 ()
{
    ofstream ostr("data.txt");

    MgcSegment3 rkSeg;
    MgcLine3 rkLine;

⌨️ 快捷键说明

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