00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4ApprQuadraticFit3.h"
00019 #include "Wm4Eigen.h"
00020
00021 namespace Wm4
00022 {
00023
00024 template <class Real>
00025 Real QuadraticFit3 (int iQuantity, const Vector3<Real>* akPoint,
00026 Real afCoeff[10])
00027 {
00028 Eigen<Real> kES(10);
00029 int iRow, iCol;
00030 for (iRow = 0; iRow < 10; iRow++)
00031 {
00032 for (iCol = 0; iCol < 10; iCol++)
00033 {
00034 kES(iRow,iCol) = (Real)0.0;
00035 }
00036 }
00037
00038 for (int i = 0; i < iQuantity; i++)
00039 {
00040 Real fX = akPoint[i].X();
00041 Real fY = akPoint[i].Y();
00042 Real fZ = akPoint[i].Z();
00043 Real fX2 = fX*fX;
00044 Real fY2 = fY*fY;
00045 Real fZ2 = fZ*fZ;
00046 Real fXY = fX*fY;
00047 Real fXZ = fX*fZ;
00048 Real fYZ = fY*fZ;
00049 Real fX3 = fX*fX2;
00050 Real fXY2 = fX*fY2;
00051 Real fXZ2 = fX*fZ2;
00052 Real fX2Y = fX*fXY;
00053 Real fX2Z = fX*fXZ;
00054 Real fXYZ = fX*fY*fZ;
00055 Real fY3 = fY*fY2;
00056 Real fYZ2 = fY*fZ2;
00057 Real fY2Z = fY*fYZ;
00058 Real fZ3 = fZ*fZ2;
00059 Real fX4 = fX*fX3;
00060 Real fX2Y2 = fX*fXY2;
00061 Real fX2Z2 = fX*fXZ2;
00062 Real fX3Y = fX*fX2Y;
00063 Real fX3Z = fX*fX2Z;
00064 Real fX2YZ = fX*fXYZ;
00065 Real fY4 = fY*fY3;
00066 Real fY2Z2 = fY*fYZ2;
00067 Real fXY3 = fX*fY3;
00068 Real fXY2Z = fX*fY2Z;
00069 Real fY3Z = fY*fY2Z;
00070 Real fZ4 = fZ*fZ3;
00071 Real fXYZ2 = fX*fYZ2;
00072 Real fXZ3 = fX*fZ3;
00073 Real fYZ3 = fY*fZ3;
00074
00075 kES(0,1) += fX;
00076 kES(0,2) += fY;
00077 kES(0,3) += fZ;
00078 kES(0,4) += fX2;
00079 kES(0,5) += fY2;
00080 kES(0,6) += fZ2;
00081 kES(0,7) += fXY;
00082 kES(0,8) += fXZ;
00083 kES(0,9) += fYZ;
00084 kES(1,4) += fX3;
00085 kES(1,5) += fXY2;
00086 kES(1,6) += fXZ2;
00087 kES(1,7) += fX2Y;
00088 kES(1,8) += fX2Z;
00089 kES(1,9) += fXYZ;
00090 kES(2,5) += fY3;
00091 kES(2,6) += fYZ2;
00092 kES(2,9) += fY2Z;
00093 kES(3,6) += fZ3;
00094 kES(4,4) += fX4;
00095 kES(4,5) += fX2Y2;
00096 kES(4,6) += fX2Z2;
00097 kES(4,7) += fX3Y;
00098 kES(4,8) += fX3Z;
00099 kES(4,9) += fX2YZ;
00100 kES(5,5) += fY4;
00101 kES(5,6) += fY2Z2;
00102 kES(5,7) += fXY3;
00103 kES(5,8) += fXY2Z;
00104 kES(5,9) += fY3Z;
00105 kES(6,6) += fZ4;
00106 kES(6,7) += fXYZ2;
00107 kES(6,8) += fXZ3;
00108 kES(6,9) += fYZ3;
00109 kES(9,9) += fY2Z2;
00110 }
00111
00112 kES(0,0) = (Real)iQuantity;
00113 kES(1,1) = kES(0,4);
00114 kES(1,2) = kES(0,7);
00115 kES(1,3) = kES(0,8);
00116 kES(2,2) = kES(0,5);
00117 kES(2,3) = kES(0,9);
00118 kES(2,4) = kES(1,7);
00119 kES(2,7) = kES(1,5);
00120 kES(2,8) = kES(1,9);
00121 kES(3,3) = kES(0,6);
00122 kES(3,4) = kES(1,8);
00123 kES(3,5) = kES(2,9);
00124 kES(3,7) = kES(1,9);
00125 kES(3,8) = kES(1,6);
00126 kES(3,9) = kES(2,6);
00127 kES(7,7) = kES(4,5);
00128 kES(7,8) = kES(4,9);
00129 kES(7,9) = kES(5,8);
00130 kES(8,8) = kES(4,6);
00131 kES(8,9) = kES(6,7);
00132 kES(9,9) = kES(5,6);
00133
00134 for (iRow = 0; iRow < 10; iRow++)
00135 {
00136 for (iCol = 0; iCol < iRow; iCol++)
00137 {
00138 kES(iRow,iCol) = kES(iCol,iRow);
00139 }
00140 }
00141
00142 Real fInvQuantity = ((Real)1.0)/(Real)iQuantity;
00143 for (iRow = 0; iRow < 10; iRow++)
00144 {
00145 for (iCol = 0; iCol < 10; iCol++)
00146 {
00147 kES(iRow,iCol) *= fInvQuantity;
00148 }
00149 }
00150
00151 kES.IncrSortEigenStuffN();
00152
00153 GVector<Real> kEVector = kES.GetEigenvector(0);
00154 size_t uiSize = 10*sizeof(Real);
00155 System::Memcpy(afCoeff,uiSize,(Real*)kEVector,uiSize);
00156
00157
00158
00159
00160 return Math<Real>::FAbs(kES.GetEigenvalue(0));
00161 }
00162
00163 template <class Real>
00164 Real QuadraticSphereFit3 (int iQuantity, const Vector3<Real>* akPoint,
00165 Vector3<Real>& rkCenter, Real& rfRadius)
00166 {
00167 Eigen<Real> kES(5);
00168 int iRow, iCol;
00169 for (iRow = 0; iRow < 5; iRow++)
00170 {
00171 for (iCol = 0; iCol < 5; iCol++)
00172 {
00173 kES(iRow,iCol) = (Real)0.0;
00174 }
00175 }
00176
00177 for (int i = 0; i < iQuantity; i++)
00178 {
00179 Real fX = akPoint[i].X();
00180 Real fY = akPoint[i].Y();
00181 Real fZ = akPoint[i].Z();
00182 Real fX2 = fX*fX;
00183 Real fY2 = fY*fY;
00184 Real fZ2 = fZ*fZ;
00185 Real fXY = fX*fY;
00186 Real fXZ = fX*fZ;
00187 Real fYZ = fY*fZ;
00188 Real fR2 = fX2+fY2+fZ2;
00189 Real fXR2 = fX*fR2;
00190 Real fYR2 = fY*fR2;
00191 Real fZR2 = fZ*fR2;
00192 Real fR4 = fR2*fR2;
00193
00194 kES(0,1) += fX;
00195 kES(0,2) += fY;
00196 kES(0,3) += fZ;
00197 kES(0,4) += fR2;
00198 kES(1,1) += fX2;
00199 kES(1,2) += fXY;
00200 kES(1,3) += fXZ;
00201 kES(1,4) += fXR2;
00202 kES(2,2) += fY2;
00203 kES(2,3) += fYZ;
00204 kES(2,4) += fYR2;
00205 kES(3,3) += fZ2;
00206 kES(3,4) += fZR2;
00207 kES(4,4) += fR4;
00208 }
00209
00210 kES(0,0) = (Real)iQuantity;
00211
00212 for (iRow = 0; iRow < 5; iRow++)
00213 {
00214 for (iCol = 0; iCol < iRow; iCol++)
00215 {
00216 kES(iRow,iCol) = kES(iCol,iRow);
00217 }
00218 }
00219
00220 Real fInvQuantity = ((Real)1.0)/(Real)iQuantity;
00221 for (iRow = 0; iRow < 5; iRow++)
00222 {
00223 for (iCol = 0; iCol < 5; iCol++)
00224 {
00225 kES(iRow,iCol) *= fInvQuantity;
00226 }
00227 }
00228
00229 kES.IncrSortEigenStuffN();
00230
00231 GVector<Real> kEVector = kES.GetEigenvector(0);
00232 Real fInv = ((Real)1.0)/kEVector[4];
00233 Real afCoeff[4];
00234 for (iRow = 0; iRow < 4; iRow++)
00235 {
00236 afCoeff[iRow] = fInv*kEVector[iRow];
00237 }
00238
00239 rkCenter.X() = -((Real)0.5)*afCoeff[1];
00240 rkCenter.Y() = -((Real)0.5)*afCoeff[2];
00241 rkCenter.Z() = -((Real)0.5)*afCoeff[3];
00242 rfRadius = Math<Real>::Sqrt(Math<Real>::FAbs(rkCenter.X()*rkCenter.X() +
00243 rkCenter.Y()*rkCenter.Y() + rkCenter.Z()*rkCenter.Z() - afCoeff[0]));
00244
00245
00246
00247
00248 return Math<Real>::FAbs(kES.GetEigenvalue(0));
00249 }
00250
00251
00252
00253
00254
00255 template WM4_FOUNDATION_ITEM
00256 float QuadraticFit3<float> (int, const Vector3<float>*, float[10]);
00257
00258 template WM4_FOUNDATION_ITEM
00259 float QuadraticSphereFit3<float> (int, const Vector3<float>*,
00260 Vector3<float>&, float&);
00261
00262 template WM4_FOUNDATION_ITEM
00263 double QuadraticFit3<double> (int, const Vector3<double>*, double[10]);
00264
00265 template WM4_FOUNDATION_ITEM
00266 double QuadraticSphereFit3<double> (int, const Vector3<double>*,
00267 Vector3<double>&, double&);
00268
00269 }