|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| #include "Wm4FoundationPCH.h"
|
| #include "Wm4ApprPlaneFit3.h"
|
| #include "Wm4Eigen.h"
|
| #include "Wm4LinearSystem.h"
|
|
|
| namespace Wm4
|
| {
|
|
|
| template <class Real>
|
| bool HeightPlaneFit3 (int iQuantity, const Vector3<Real>* akPoint, Real& rfA,
|
| Real& rfB, Real& rfC)
|
| {
|
|
|
|
|
|
|
|
|
|
|
|
|
| Real fSumX = (Real)0.0, fSumY = (Real)0.0, fSumZ = (Real)0.0;
|
| Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
|
| Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0;
|
| int i;
|
| for (i = 0; i < iQuantity; i++)
|
| {
|
| fSumX += akPoint[i].X();
|
| fSumY += akPoint[i].Y();
|
| fSumZ += akPoint[i].Z();
|
| fSumXX += akPoint[i].X()*akPoint[i].X();
|
| fSumXY += akPoint[i].X()*akPoint[i].Y();
|
| fSumXZ += akPoint[i].X()*akPoint[i].Z();
|
| fSumYY += akPoint[i].Y()*akPoint[i].Y();
|
| fSumYZ += akPoint[i].Y()*akPoint[i].Z();
|
| }
|
|
|
| Real aafA[3][3] =
|
| {
|
| {fSumXX, fSumXY, fSumX},
|
| {fSumXY, fSumYY, fSumY},
|
| {fSumX, fSumY, (Real)iQuantity}
|
| };
|
|
|
| Real afB[3] =
|
| {
|
| fSumXZ,
|
| fSumYZ,
|
| fSumZ
|
| };
|
|
|
| Real afX[3];
|
|
|
| bool bNonsingular = LinearSystem<Real>().Solve3(aafA,afB,afX);
|
| if (bNonsingular)
|
| {
|
| rfA = afX[0];
|
| rfB = afX[1];
|
| rfC = afX[2];
|
| }
|
| else
|
| {
|
| rfA = Math<Real>::MAX_REAL;
|
| rfB = Math<Real>::MAX_REAL;
|
| rfC = Math<Real>::MAX_REAL;
|
| }
|
|
|
| return bNonsingular;
|
| }
|
|
|
| template <class Real>
|
| Plane3<Real> OrthogonalPlaneFit3 (int iQuantity, const Vector3<Real>* akPoint)
|
| {
|
|
|
| Vector3<Real> kOrigin = Vector3<Real>::ZERO;
|
| int i;
|
| for (i = 0; i < iQuantity; i++)
|
| {
|
| kOrigin += akPoint[i];
|
| }
|
| Real fInvQuantity = ((Real)1.0)/iQuantity;
|
| kOrigin *= fInvQuantity;
|
|
|
|
|
| Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
|
| Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0, fSumZZ = (Real)0.0;
|
| for (i = 0; i < iQuantity; i++)
|
| {
|
| Vector3<Real> kDiff = akPoint[i] - kOrigin;
|
| fSumXX += kDiff.X()*kDiff.X();
|
| fSumXY += kDiff.X()*kDiff.Y();
|
| fSumXZ += kDiff.X()*kDiff.Z();
|
| fSumYY += kDiff.Y()*kDiff.Y();
|
| fSumYZ += kDiff.Y()*kDiff.Z();
|
| fSumZZ += kDiff.Z()*kDiff.Z();
|
| }
|
|
|
| fSumXX *= fInvQuantity;
|
| fSumXY *= fInvQuantity;
|
| fSumXZ *= fInvQuantity;
|
| fSumYY *= fInvQuantity;
|
| fSumYZ *= fInvQuantity;
|
| fSumZZ *= fInvQuantity;
|
|
|
|
|
| Eigen<Real> kES(3);
|
| kES(0,0) = fSumXX;
|
| kES(0,1) = fSumXY;
|
| kES(0,2) = fSumXZ;
|
| kES(1,0) = fSumXY;
|
| kES(1,1) = fSumYY;
|
| kES(1,2) = fSumYZ;
|
| kES(2,0) = fSumXZ;
|
| kES(2,1) = fSumYZ;
|
| kES(2,2) = fSumZZ;
|
|
|
|
|
| kES.DecrSortEigenStuff3();
|
|
|
|
|
| Vector3<Real> kNormal;
|
| kES.GetEigenvector(2,kNormal);
|
|
|
|
|
| return Plane3<Real>(kNormal,kOrigin);
|
| }
|
|
|
|
|
|
|
|
|
|
|
| template WM4_FOUNDATION_ITEM
|
| bool HeightPlaneFit3<float> (int, const Vector3<float>*, float&, float&,
|
| float&);
|
|
|
| template WM4_FOUNDATION_ITEM
|
| Plane3<float> OrthogonalPlaneFit3<float> (int, const Vector3<float>*);
|
|
|
| template WM4_FOUNDATION_ITEM
|
| bool HeightPlaneFit3<double> (int, const Vector3<double>*, double&, double&,
|
| double&);
|
|
|
| template WM4_FOUNDATION_ITEM
|
| Plane3<double> OrthogonalPlaneFit3<double> (int, const Vector3<double>*);
|
|
|
| }
|
|
|