📄 testdistance.cpp
字号:
// 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 + -