Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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
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
00044
00045
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
00054
00055 Matrix22 A2_MK;
00056 dirX.normalize();
00057
00058
00059 if( !dirX.allFinite() ) {
00060 dirX.setZero();
00061 dirX(0)= 1;
00062 }
00063
00064 Vector2 dirY(-dirX(1),dirX(0));
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);
00074 aabb.unite(p);
00075 }
00076
00077
00078
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
00089
00090 Matrix33 A_KM;
00091 A_KM.setIdentity();
00092 A_KM.block<2,2>(0,0) = A2_MK.transpose();
00093
00094
00095
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
00115
00116
00117
00118
00119 MinAreaRectangle mar(m_p);
00120 mar.compute();
00121 auto rect = mar.getMinRectangle();
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 Matrix22 A2_KM;
00137
00138
00139
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
00155
00156 Matrix33 A_IM;
00157
00158 A_IM.setIdentity();
00159 A_IM.block<2,2>(0,0) = A2_KM;
00160
00161 A_IM = m_A_KI.transpose()*A_IM;
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
00178 Vector3 xDir,yDir;
00179
00180 makeCoordinateSystem(m_zDir,xDir,yDir);
00181
00182
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
00191 auto size = points.cols();
00192 m_p.resize(2,size);
00193
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