Wm4ApprSphereFit3.cpp

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4ApprSphereFit3.h"
00019 #include "Wm4ApprQuadraticFit3.h"
00020 
00021 namespace Wm4
00022 {
00023 //----------------------------------------------------------------------------
00024 template <class Real>
00025 bool SphereFit3 (int iQuantity, const Vector3<Real>* akPoint,
00026     int iMaxIterations, Sphere3<Real>& rkSphere,
00027     bool bInitialCenterIsAverage)
00028 {
00029     // compute the average of the data points
00030     Vector3<Real> kAverage = akPoint[0];
00031     int i0;
00032     for (i0 = 1; i0 < iQuantity; i0++)
00033     {
00034         kAverage += akPoint[i0];
00035     }
00036     Real fInvQuantity = ((Real)1.0)/(Real)iQuantity;
00037     kAverage *= fInvQuantity;
00038 
00039     // initial guess
00040     if (bInitialCenterIsAverage)
00041     {
00042         rkSphere.Center = kAverage;
00043     }
00044     else
00045     {
00046         QuadraticSphereFit3<Real>(iQuantity,akPoint,rkSphere.Center,
00047             rkSphere.Radius);
00048     }
00049 
00050     int i1;
00051     for (i1 = 0; i1 < iMaxIterations; i1++)
00052     {
00053         // update the iterates
00054         Vector3<Real> kCurrent = rkSphere.Center;
00055 
00056         // compute average L, dL/da, dL/db, dL/dc
00057         Real fLAverage = (Real)0.0;
00058         Vector3<Real> kDerLAverage = Vector3<Real>::ZERO;
00059         for (i0 = 0; i0 < iQuantity; i0++)
00060         {
00061             Vector3<Real> kDiff = akPoint[i0] - rkSphere.Center;
00062             Real fLength = kDiff.Length();
00063             if (fLength > Math<Real>::ZERO_TOLERANCE)
00064             {
00065                 fLAverage += fLength;
00066                 Real fInvLength = ((Real)1.0)/fLength;
00067                 kDerLAverage -= fInvLength*kDiff;
00068             }
00069         }
00070         fLAverage *= fInvQuantity;
00071         kDerLAverage *= fInvQuantity;
00072 
00073         rkSphere.Center = kAverage + fLAverage*kDerLAverage;
00074         rkSphere.Radius = fLAverage;
00075 
00076         Vector3<Real> kDiff = rkSphere.Center - kCurrent;
00077         if (Math<Real>::FAbs(kDiff.X()) <= Math<Real>::ZERO_TOLERANCE
00078         &&  Math<Real>::FAbs(kDiff.Y()) <= Math<Real>::ZERO_TOLERANCE
00079         &&  Math<Real>::FAbs(kDiff.Z()) <= Math<Real>::ZERO_TOLERANCE)
00080         {
00081             break;
00082         }
00083     }
00084 
00085     return i1 < iMaxIterations;
00086 }
00087 //----------------------------------------------------------------------------
00088 
00089 //----------------------------------------------------------------------------
00090 // explicit instantiation
00091 //----------------------------------------------------------------------------
00092 template WM4_FOUNDATION_ITEM
00093 bool SphereFit3<float> (int, const Vector3<float>*, int, Sphere3<float>&,
00094     bool);
00095 
00096 template WM4_FOUNDATION_ITEM
00097 bool SphereFit3<double> (int, const Vector3<double>*, int, Sphere3<double>&,
00098     bool);
00099 //----------------------------------------------------------------------------
00100 }

Generated on Wed Nov 23 19:01:02 2011 for FreeCAD by  doxygen 1.6.1