ProjectedPointSet.hpp
Go to the documentation of this file.
00001 // ========================================================================================
00002 //  ApproxMVBB
00003 //  Copyright (C) 2014 by Gabriel Nützi <nuetzig (at) imes (d0t) mavt (d0t) ethz (døt) ch>
00004 //
00005 //  This Source Code Form is subject to the terms of the Mozilla Public
00006 //  License, v. 2.0. If a copy of the MPL was not distributed with this
00007 //  file, You can obtain one at http://mozilla.org/MPL/2.0/.
00008 // ========================================================================================
00009 #ifndef ApproxMVBB_ProjectedPointSet_hpp
00010 #define ApproxMVBB_ProjectedPointSet_hpp
00011 
00012 #include "ApproxMVBB/Config/Config.hpp"
00013 
00014 #include ApproxMVBB_AssertionDebug_INCLUDE_FILE
00015 #include ApproxMVBB_TypeDefs_INCLUDE_FILE
00016 
00017 #include "ApproxMVBB/TypeDefsPoints.hpp"
00018 
00019 #include "ApproxMVBB/PointFunctions.hpp"
00020 #include "ApproxMVBB/MakeCoordinateSystem.hpp"
00021 #include ApproxMVBB_OOBB_INCLUDE_FILE
00022 #include "ApproxMVBB/MinAreaRectangle.hpp"
00023 
00024 //#include "TestFunctions.hpp"
00025 
00026 namespace ApproxMVBB{
00027 class APPROXMVBB_EXPORT ProjectedPointSet {
00028 public:
00029     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00030     ApproxMVBB_DEFINE_MATRIX_TYPES
00031     ApproxMVBB_DEFINE_POINTS_CONFIG_TYPES
00032 
00033     template<typename Derived>
00034     OOBB computeMVBBApprox(const Vector3 & zDir,
00035                            const MatrixBase<Derived> & points,
00036                            const PREC epsilon) {
00037 
00038         EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
00039 
00040         using namespace PointFunctions;
00041         m_zDir = zDir;
00042         project(points);
00043         //std::cout <<"projected points" <<std::endl;
00044 
00045         // Estimate diameter in 2d projective plane
00046         std::pair<Vector2,Vector2> pp = estimateDiameter<2>(m_p,epsilon);
00047 
00048 
00049         Vector2 dirX = pp.first - pp.second;
00050         if( ( pp.second.array() >=  pp.first.array()).all() ) {
00051             dirX *= -1;
00052         }
00053         //std::cout <<"estimated 2d diameter: " << dirX.transpose() << " eps: " << epsilon << std::endl;
00054         // Built Coordinate Trafo from frame K to frame M
00055         Matrix22 A2_MK;
00056         dirX.normalize();
00057 
00058          // If normalized direction INf/NaN, use (1,0)
00059         if( !dirX.allFinite() ) {
00060             dirX.setZero();
00061             dirX(0)= 1;
00062         }
00063 
00064         Vector2 dirY(-dirX(1),dirX(0));  // Positive rotation of 90 degrees
00065         A2_MK.col(0) = dirX;
00066         A2_MK.col(1) = dirY;
00067         A2_MK.transposeInPlace();
00068 
00069         AABB2d aabb;
00070         Vector2 p;
00071         auto size = m_p.cols();
00072         for(unsigned int i=0; i < size; ++i) {
00073             p.noalias() = A2_MK * m_p.col(i); // Transform all points
00074             aabb.unite(p);
00075         }
00076 
00077 //         std::cout << "aabb_min: "<<  aabb.m_minPoint.transpose() << std::endl;
00078 //         std::cout << "aabb_max: "<< aabb.m_maxPoint.transpose() << std::endl;
00079 
00080         Vector3 M_min;
00081         M_min.head<2>() = aabb.m_minPoint;
00082         M_min(2) = m_minZValue;
00083 
00084         Vector3 M_max;
00085         M_max.head<2>() = aabb.m_maxPoint;
00086         M_max(2) = m_maxZValue;
00087 
00088         // Make coordinate transformation from M frame (Minimum Rectancle)
00089         // to K frame (Projection Plane);
00090         Matrix33 A_KM;
00091         A_KM.setIdentity();
00092         A_KM.block<2,2>(0,0) =  A2_MK.transpose();
00093 
00094 //         std::cout << "M_min: "<< M_min.transpose() << std::endl;
00095 //         std::cout << "M_max: "<< M_max.transpose() << std::endl;
00096 
00097         return OOBB(M_min,M_max, m_A_KI.transpose()*A_KM );
00098     }
00099 
00104     template<typename Derived>
00105     OOBB computeMVBB(const Vector3 & zDir,
00106                      const MatrixBase<Derived> & points ) {
00107 
00108         EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,Eigen::Dynamic)
00109 
00110         using namespace CoordinateSystem;
00111         m_zDir = zDir;
00112         project(points);
00113 
00114         // compute minimum area rectangle first
00115         // std::cout << "Dump points DEBUG:" << std::endl;
00116         //TestFunctions::dumpPointsMatrixBinary("DumpedPoints.bin",m_p);
00117 
00118 
00119         MinAreaRectangle mar(m_p);
00120         mar.compute();
00121         auto rect = mar.getMinRectangle();
00122 
00123         //std::cout << "Dump RECT DEBUG:" << std::endl;
00124         // Vector2List p;
00125         //p.push_back( rect.m_p);
00126         //p.push_back( rect.m_p + rect.m_u );
00127         //p.push_back( rect.m_p + rect.m_u + rect.m_v );
00128         //p.push_back( rect.m_p + rect.m_v );
00129         //p.push_back( rect.m_p);
00130 
00131         //TestFunctions::dumpPoints("./MinAreaRectangleTest13" "Out.txt",p);
00132 
00133 
00134         // Box coordinates are in K Frame
00135 
00136         Matrix22 A2_KM;
00137 
00138 //        std::cout << "u:" << rect.m_u.norm() << std::endl;
00139 //        std::cout << "v:" << rect.m_v.norm() << std::endl;
00140 
00141         A2_KM.col(0) = rect.m_u;
00142         A2_KM.col(1) = rect.m_v;
00143 
00144         Vector2 M_p = A2_KM.transpose()*rect.m_p;
00145 
00146         Vector3 M_min;
00147         M_min.head<2>() = M_p;
00148         M_min(2) = m_minZValue;
00149 
00150         Vector3 M_max(rect.m_uL, rect.m_vL, 0.0);
00151         M_max.head<2>() += M_p;
00152         M_max(2) = m_maxZValue;
00153 
00154         // Make coordinate transformation from M frame (Minimum Rectancle)
00155         // to K frame (Projection Plane);
00156         Matrix33 A_IM;
00157         // Make A_KM
00158         A_IM.setIdentity();
00159         A_IM.block<2,2>(0,0) =  A2_KM;
00160         // Make A_IM;
00161         A_IM = m_A_KI.transpose()*A_IM; // A_IM = A_IK * A_KM
00162 
00163         return OOBB(M_min,M_max, A_IM );
00164     }
00165 
00166 
00167 private:
00168 
00169     template<typename Derived>
00170     void project(const MatrixBase<Derived> & points) {
00171         using namespace CoordinateSystem;
00172 
00173         if(points.cols()==0) {
00174             ApproxMVBB_ERRORMSG("Point set empty!");
00175         }
00176 
00177         // Generate Orthonormal Bases
00178         Vector3 xDir,yDir;
00179         //std::cout << "dir: " <<  m_zDir << std::endl;
00180         makeCoordinateSystem(m_zDir,xDir,yDir);
00181 
00182         //Make coodinate transform from frame I to K!
00183         m_A_KI.col(0) = xDir;
00184         m_A_KI.col(1) = yDir;
00185         m_A_KI.col(2) = m_zDir;
00186         m_A_KI.transposeInPlace();
00187         ApproxMVBB_ASSERTMSG(checkOrthogonality(xDir,yDir,m_zDir,1e-6),
00188                   "Not orthogonal: x:"<<xDir.transpose()<< " y: "<< yDir.transpose() << " z: "  << m_zDir.transpose());
00189 
00190         // Project Points onto xDir,yDir Halfspace
00191         auto size = points.cols();
00192         m_p.resize(2,size);
00193         //m_p = m_A_KI * points;  // Project points! (below is faster)
00194         Vector3 p;
00195         m_maxZValue = std::numeric_limits<PREC>::lowest();
00196         m_minZValue = std::numeric_limits<PREC>::max();
00197         for(decltype(size) i=0; i<size; ++i) {
00198             p = m_A_KI*points.col(i);
00199             m_p.col(i) = p.head<2>();
00200             m_maxZValue = std::max(m_maxZValue,p(2));
00201             m_minZValue = std::min(m_minZValue,p(2));
00202         }
00203 
00204 
00205     }
00206 
00207     Matrix2Dyn  m_p; 
00208 
00209     Vector3 m_zDir;
00210     Matrix33 m_A_KI; 
00211     PREC m_minZValue, m_maxZValue;
00212 
00213 };
00214 }
00215 #endif


asr_approx_mvbb
Author(s): Gassner Nikolai
autogenerated on Sat Jun 8 2019 20:21:50