plane3D.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_GEOMETRY_PLANE3D_H_
00016 #define _DLR_GEOMETRY_PLANE3D_H_
00017 
00018 #include <iostream>
00019 #include <dlrNumeric/vector3D.h>
00020 
00021 // xxx
00022 #include <dlrNumeric/utilities.h>
00023 
00024 namespace dlr {
00025 
00026   namespace geometry {
00027     
00031     class Plane3D {
00032     public:
00033       
00037       Plane3D()
00038         : m_origin(0.0, 0.0, 0.0), m_directionVector0(1.0, 0.0, 0.0),
00039           m_directionVector1(0.0, 1.0, 0.0) {}
00040 
00041     
00058       Plane3D(const Vector3D& point0,
00059               const Vector3D& point1,
00060               const Vector3D& point2,
00061               bool orthonormalize = true);
00062 
00063     
00080       template <class Iterator> 
00081       Plane3D(Iterator beginIterator,
00082               Iterator endIterator,
00083               double inlierPercentage = 1.0);
00084 
00085     
00091       Plane3D(const Plane3D& source);
00092 
00093 
00097       ~Plane3D() {}
00098 
00099 
00107       Plane3D&
00108       operator=(const Plane3D& source);
00109 
00110 
00122       const Vector3D&
00123       getDirectionVector0() const {return m_directionVector0;}
00124       
00125 
00137       const Vector3D&
00138       getDirectionVector1() const {return m_directionVector1;}
00139 
00140 
00141       // xxx
00142       Vector3D
00143       getNormal() const {
00144         return dlr::cross(m_directionVector0, m_directionVector1);
00145       }
00146       
00147 
00156       const Vector3D&
00157       getOrigin() const {return m_origin;}
00158 
00159       // xxx
00160       double
00161       findDistance(const Vector3D& point) {
00162         Vector3D offset = point - m_origin;
00163         offset -= dot(offset, m_directionVector0) * m_directionVector0;
00164         offset -= dot(offset, m_directionVector1) * m_directionVector1;
00165         return magnitude(offset);
00166       }
00167         
00168       
00169     private:
00170       // Private member functions.
00171       template <class Iterator> 
00172       void
00173       estimateFromSequence(Iterator beginIterator,
00174                            Iterator endIterator);
00175 
00176 
00177       // Private data members.
00178       Vector3D m_origin;
00179       Vector3D m_directionVector0;
00180       Vector3D m_directionVector1;
00181 
00182     }; // class Plane3D
00183 
00184 
00185 
00186     /* ======= Non-member functions. ======= */
00187 
00188     std::ostream&
00189     operator<<(std::ostream& stream, const Plane3D& plane);
00190     
00191     
00192   } // namespace utilities
00193     
00194 } // namespace dlr
00195 
00196 
00197 /* ======= Inline and template function definitions. ======= */
00198 
00199 #include <dlrLinearAlgebra/linearAlgebra.h>
00200 #include <dlrNumeric/subArray1D.h>
00201 
00202 namespace dlr {
00203 
00204   namespace geometry {
00205 
00206 
00207     // This constructor initializes the plane using a collection of
00208     // points.
00209     template <class Iterator>
00210     Plane3D::
00211     Plane3D(Iterator beginIterator,
00212             Iterator endIterator,
00213             double inlierPercentage)
00214       : m_origin(0.0, 0.0, 0.0),
00215         m_directionVector0(1.0, 0.0, 0.0),
00216         m_directionVector1(0.0, 1.0, 0.0)
00217     {
00218       // Note(xxx): Hasty implementation!  Clean up soon.
00219       std::vector<Vector3D> allPointsVector;
00220       std::copy(beginIterator, endIterator,
00221                 std::back_inserter(allPointsVector));
00222 
00223       int numberToInclude =
00224         static_cast<int>(allPointsVector.size() * inlierPercentage + 0.5);
00225       int numberToIgnore = allPointsVector.size() - numberToInclude;
00226 
00227       Array1D<double> distances(allPointsVector.size());
00228       Array1D<size_t> ignoredPoints(numberToIgnore);
00229       Array1D<Vector3D> currentPoints(allPointsVector.size());
00230       std::copy(allPointsVector.begin(), allPointsVector.end(),
00231                 currentPoints.begin());
00232       bool isDone = false;
00233       ignoredPoints = 0;
00234       // xxx
00235       size_t iterationCount = 0;
00236       while(!isDone) {
00237         this->estimateFromSequence(currentPoints.begin(), currentPoints.end());
00238         for(size_t index0 = 0; index0 < allPointsVector.size(); ++index0) {
00239           distances[index0] = this->findDistance(allPointsVector[index0]);
00240         }
00241         Array1D<size_t> pointIndices = argsort(distances);
00242         if(static_cast<int>(currentPoints.size()) != numberToInclude) {
00243           currentPoints.reinit(numberToInclude);
00244         }
00245         for(int index1 = 0; index1 < numberToInclude; ++index1) {
00246           currentPoints[index1] = allPointsVector[pointIndices[index1]];
00247         }
00248         int index3 = 0;
00249         isDone = true;
00250         for(int index2 = numberToInclude;
00251             index2 < static_cast<int>(allPointsVector.size());
00252             ++index2) {
00253           if(ignoredPoints[index3] != pointIndices[index2]) {
00254             isDone = false;
00255             break;
00256           }
00257         }
00258         // xxx
00259         if(++iterationCount >= 3) {
00260           break;
00261         }
00262         if(numberToInclude < static_cast<int>(allPointsVector.size())) {
00263           ignoredPoints = subArray(pointIndices, Slice(numberToInclude, 0));
00264         } else {
00265           ignoredPoints.clear();
00266         }
00267       }
00268     }
00269 
00270 
00271 
00272     template <class Iterator> 
00273     void
00274     Plane3D::
00275     estimateFromSequence(Iterator beginIterator,
00276                          Iterator endIterator)
00277     {
00278       // Get mean point.
00279       dlr::Vector3D meanPoint;
00280       Iterator targetIterator = beginIterator;
00281       size_t count = 0;
00282       while(targetIterator != endIterator) {
00283         meanPoint += *targetIterator;
00284         ++count;
00285         ++targetIterator;
00286       }
00287       meanPoint /= static_cast<double>(count);
00288 
00289       // Get 3x3 covariance matrix.
00290       dlr::Array2D<double> covarianceMatrix(3, 3);
00291       covarianceMatrix = 0.0;
00292       targetIterator = beginIterator;
00293       while(targetIterator != endIterator) {
00294         const double xValue = targetIterator->x() - meanPoint.x();
00295         const double yValue = targetIterator->y() - meanPoint.y();
00296         const double zValue = targetIterator->z() - meanPoint.z();
00297         covarianceMatrix(0, 0) += xValue * xValue;
00298         covarianceMatrix(0, 1) += xValue * yValue;
00299         covarianceMatrix(0, 2) += xValue * zValue;
00300         covarianceMatrix(1, 1) += yValue * yValue;
00301         covarianceMatrix(1, 2) += yValue * zValue;
00302         covarianceMatrix(2, 2) += zValue * zValue;
00303         ++targetIterator;
00304       }
00305       covarianceMatrix(1, 0) = covarianceMatrix(0, 1);
00306       covarianceMatrix(2, 0) = covarianceMatrix(0, 2);
00307       covarianceMatrix(2, 1) = covarianceMatrix(1, 2);
00308       covarianceMatrix /= static_cast<double>(count);
00309       
00310       // Solve for best fit plane.
00311       dlr::Array1D<double> eigenvalues;
00312       dlr::Array2D<double> eigenvectors;
00313       dlr::linearAlgebra::eigenvectorsSymmetric(
00314         covarianceMatrix, eigenvalues, eigenvectors);
00315       dlr::Vector3D direction0(
00316         eigenvectors(0, 0), eigenvectors(1, 0), eigenvectors(2, 0));
00317       dlr::Vector3D direction1(
00318         eigenvectors(0, 1), eigenvectors(1, 1), eigenvectors(2, 1));
00319       direction0 /= dlr::magnitude(direction0);
00320       direction1 /= dlr::magnitude(direction1);
00321 
00322       m_origin = meanPoint;
00323       m_directionVector0 = direction0;
00324       m_directionVector1 = direction1;
00325     }
00326 
00327     
00328   } // namespace geometry
00329   
00330 } // namespace dlr
00331 
00332 
00333 #endif /* #ifndef _DLR_GEOMETRY_PLANE3D_H_ */

Generated on Mon Jul 9 20:34:03 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2