00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4ApprPlaneFit3.h"
00019 #include "Wm4Eigen.h"
00020 #include "Wm4LinearSystem.h"
00021
00022 namespace Wm4
00023 {
00024
00025 template <class Real>
00026 bool HeightPlaneFit3 (int iQuantity, const Vector3<Real>* akPoint, Real& rfA,
00027 Real& rfB, Real& rfC)
00028 {
00029
00030
00031
00032
00033
00034
00035 Real fSumX = (Real)0.0, fSumY = (Real)0.0, fSumZ = (Real)0.0;
00036 Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
00037 Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0;
00038 int i;
00039 for (i = 0; i < iQuantity; i++)
00040 {
00041 fSumX += akPoint[i].X();
00042 fSumY += akPoint[i].Y();
00043 fSumZ += akPoint[i].Z();
00044 fSumXX += akPoint[i].X()*akPoint[i].X();
00045 fSumXY += akPoint[i].X()*akPoint[i].Y();
00046 fSumXZ += akPoint[i].X()*akPoint[i].Z();
00047 fSumYY += akPoint[i].Y()*akPoint[i].Y();
00048 fSumYZ += akPoint[i].Y()*akPoint[i].Z();
00049 }
00050
00051 Real aafA[3][3] =
00052 {
00053 {fSumXX, fSumXY, fSumX},
00054 {fSumXY, fSumYY, fSumY},
00055 {fSumX, fSumY, (Real)iQuantity}
00056 };
00057
00058 Real afB[3] =
00059 {
00060 fSumXZ,
00061 fSumYZ,
00062 fSumZ
00063 };
00064
00065 Real afX[3];
00066
00067 bool bNonsingular = LinearSystem<Real>().Solve3(aafA,afB,afX);
00068 if (bNonsingular)
00069 {
00070 rfA = afX[0];
00071 rfB = afX[1];
00072 rfC = afX[2];
00073 }
00074 else
00075 {
00076 rfA = Math<Real>::MAX_REAL;
00077 rfB = Math<Real>::MAX_REAL;
00078 rfC = Math<Real>::MAX_REAL;
00079 }
00080
00081 return bNonsingular;
00082 }
00083
00084 template <class Real>
00085 Plane3<Real> OrthogonalPlaneFit3 (int iQuantity, const Vector3<Real>* akPoint)
00086 {
00087
00088 Vector3<Real> kOrigin = Vector3<Real>::ZERO;
00089 int i;
00090 for (i = 0; i < iQuantity; i++)
00091 {
00092 kOrigin += akPoint[i];
00093 }
00094 Real fInvQuantity = ((Real)1.0)/iQuantity;
00095 kOrigin *= fInvQuantity;
00096
00097
00098 Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
00099 Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0, fSumZZ = (Real)0.0;
00100 for (i = 0; i < iQuantity; i++)
00101 {
00102 Vector3<Real> kDiff = akPoint[i] - kOrigin;
00103 fSumXX += kDiff.X()*kDiff.X();
00104 fSumXY += kDiff.X()*kDiff.Y();
00105 fSumXZ += kDiff.X()*kDiff.Z();
00106 fSumYY += kDiff.Y()*kDiff.Y();
00107 fSumYZ += kDiff.Y()*kDiff.Z();
00108 fSumZZ += kDiff.Z()*kDiff.Z();
00109 }
00110
00111 fSumXX *= fInvQuantity;
00112 fSumXY *= fInvQuantity;
00113 fSumXZ *= fInvQuantity;
00114 fSumYY *= fInvQuantity;
00115 fSumYZ *= fInvQuantity;
00116 fSumZZ *= fInvQuantity;
00117
00118
00119 Eigen<Real> kES(3);
00120 kES(0,0) = fSumXX;
00121 kES(0,1) = fSumXY;
00122 kES(0,2) = fSumXZ;
00123 kES(1,0) = fSumXY;
00124 kES(1,1) = fSumYY;
00125 kES(1,2) = fSumYZ;
00126 kES(2,0) = fSumXZ;
00127 kES(2,1) = fSumYZ;
00128 kES(2,2) = fSumZZ;
00129
00130
00131 kES.DecrSortEigenStuff3();
00132
00133
00134 Vector3<Real> kNormal;
00135 kES.GetEigenvector(2,kNormal);
00136
00137
00138 return Plane3<Real>(kNormal,kOrigin);
00139 }
00140
00141
00142
00143
00144
00145 template WM4_FOUNDATION_ITEM
00146 bool HeightPlaneFit3<float> (int, const Vector3<float>*, float&, float&,
00147 float&);
00148
00149 template WM4_FOUNDATION_ITEM
00150 Plane3<float> OrthogonalPlaneFit3<float> (int, const Vector3<float>*);
00151
00152 template WM4_FOUNDATION_ITEM
00153 bool HeightPlaneFit3<double> (int, const Vector3<double>*, double&, double&,
00154 double&);
00155
00156 template WM4_FOUNDATION_ITEM
00157 Plane3<double> OrthogonalPlaneFit3<double> (int, const Vector3<double>*);
00158
00159 }