AABB.hpp
Go to the documentation of this file.
1 // ========================================================================================
2 // ApproxMVBB
3 // Copyright (C) 2014 by Gabriel Nützi <nuetzig (at) imes (d0t) mavt (d0t) ethz (døt) ch>
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 // ========================================================================================
9 
10 #ifndef ApproxMVBB_AABB_hpp
11 #define ApproxMVBB_AABB_hpp
12 
13 #include <algorithm>
14 
16 #include ApproxMVBB_TypeDefs_INCLUDE_FILE
17 #include ApproxMVBB_StaticAssert_INCLUDE_FILE
18 #include ApproxMVBB_AssertionDebug_INCLUDE_FILE
19 
20 namespace ApproxMVBB{
21 
22 template<unsigned int Dim>
23 class AABB {
24 public:
26  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
27 private:
28 
29  template<unsigned int D = Dim, bool = true>
30  struct unite_impl{
31  template<typename T, typename P>
32  inline static void apply(T * t, const P & p){
33  t->m_maxPoint(D-1) = std::max(t->m_maxPoint(D-1),p(D-1));
34  t->m_minPoint(D-1) = std::min(t->m_minPoint(D-1),p(D-1));
36  }
37  };
38  template<bool dummy>
39  struct unite_impl<0,dummy>{
40  template<typename T, typename P>
41  inline static void apply(T *, const P &){}
42  };
43 
44  template<unsigned int D = Dim, bool = true>
45  struct uniteBox_impl{
46  template<typename T, typename B>
47  inline static void apply(T * t, const B & b){
48  t->m_maxPoint(D-1) = std::max(t->m_maxPoint(D-1),b.m_maxPoint(D-1));
49  t->m_minPoint(D-1) = std::min(t->m_minPoint(D-1),b.m_minPoint(D-1));
51  }
52  };
53  template<bool dummy>
54  struct uniteBox_impl<0,dummy>{
55  template<typename T, typename B>
56  inline static void apply(T *, const B &){}
57  };
58 
59 
60  template<unsigned int D = Dim, bool = true>
61  struct reset_impl{
62  template<typename T>
63  inline static void apply(T * t){
64  t->m_minPoint(D-1) = std::numeric_limits<PREC>::max();
65  t->m_maxPoint(D-1) = std::numeric_limits<PREC>::lowest();
67  }
68  };
69 
70  template<bool dummy>
71  struct reset_impl<0,dummy>{
72  template<typename T>
73  inline static void apply(T *){}
74  };
75 
76 public:
77 
78  AABB() {
79  reset();
80  }
81  void reset(){
82  reset_impl<>::apply(this);
83  }
84 
85  AABB( const VectorStat<Dim> &p): m_minPoint(p), m_maxPoint(p) {}
86 
87  AABB( const VectorStat<Dim> &l, const VectorStat<Dim> &u): m_minPoint(l), m_maxPoint(u) {
88  ApproxMVBB_ASSERTMSG( (m_maxPoint.array() >= m_minPoint.array()).all(),
89  "AABB initialized wrongly! min/max: " << m_minPoint.transpose() <<"/" << m_maxPoint.transpose());
90  }
91 
92 
93  template<typename Derived>
94  AABB& unite(const MatrixBase<Derived> &p) {
95  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,Dim);
96  unite_impl<>::apply(this,p);
97  return *this;
98  }
99 
100  template<typename Derived>
101  AABB& operator+=(const MatrixBase<Derived> &p){
102  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,Dim);
103  unite_impl<>::apply(this,p);
104  return *this;
105  }
106 
107 
108  void unite(const AABB & box) {
109  uniteBox_impl<>::apply(this,box);
110  }
111 
112  AABB& operator+=(const AABB & box){
113  uniteBox_impl<>::apply(this,box);
114  return *this;
115  }
116 
117  AABB operator+ (const AABB & box){
118  AABB r = this;
119  uniteBox_impl<>::apply(&r,box);
120  return r;
121  }
122 
123  AABB& transform(const AffineTrafo & M) {
124  ApproxMVBB_STATIC_ASSERTM(Dim==3,"So far AABB transform is only implemented in 3d")
125  AABB ret( M*(Vector3( m_minPoint(0), m_minPoint(1), m_minPoint(2))));
126  ret.unite(M*(Vector3( m_maxPoint(0), m_minPoint(1), m_minPoint(2))));
127  ret.unite(M*(Vector3( m_minPoint(0), m_maxPoint(1), m_minPoint(2))));
128  ret.unite(M*(Vector3( m_minPoint(0), m_minPoint(1), m_maxPoint(2))));
129  ret.unite(M*(Vector3( m_minPoint(0), m_maxPoint(1), m_maxPoint(2))));
130  ret.unite(M*(Vector3( m_maxPoint(0), m_maxPoint(1), m_minPoint(2))));
131  ret.unite(M*(Vector3( m_maxPoint(0), m_minPoint(1), m_maxPoint(2))));
132  ret.unite(M*(Vector3( m_maxPoint(0), m_maxPoint(1), m_maxPoint(2))));
133  *this = ret;
134  return *this;
135  }
136 
137 
138  inline VectorStat<Dim> center(){ return 0.5*(m_maxPoint + m_minPoint);}
139 
140  inline bool overlaps(const AABB & box) const {
141  return ((m_maxPoint.array() >= box.m_minPoint.array()) && (m_minPoint.array() <= box.m_maxPoint.array())).all();
142  }
143 
144  template<typename Derived>
145  inline bool overlaps(const MatrixBase<Derived> &p) const {
146  return ((p.array() >= m_minPoint.array()) && (p.array() <= m_maxPoint.array())).all();
147  }
148 
149  inline bool overlapsSubSpace(const AABB & box, unsigned int fixedAxis) const {
150  MyMatrix::ArrayStat<bool,Dim> t = ((m_maxPoint.array() >= box.m_minPoint.array()) && (m_minPoint.array() <= box.m_maxPoint.array()));
151  t(fixedAxis) = true;
152  return t.all();
153  }
154 
155  inline ArrayStat<Dim> extent() const{
156  // since min <= max, extent can not be smaller than zero
157  // , except if AABB contains no points/uninitialized (reset())
158  return (m_maxPoint - m_minPoint).array();
159  }
160 
161  inline PREC maxExtent() const{
162  return (m_maxPoint - m_minPoint).maxCoeff();
163  }
164 
165  inline bool isEmpty() const {
166  return (m_maxPoint.array() <= m_minPoint.array()).any();
167  }
168 
169  inline void expand(PREC d) {
170  ApproxMVBB_ASSERTMSG(d>=0,"d>=0")
171  m_minPoint.array() -= d;
172  m_maxPoint.array() += d;
173  }
174 
175  inline void expand(VectorStat<Dim> d) {
176  ApproxMVBB_ASSERTMSG((d.array()>=0).all(), "d<0")
177  m_minPoint -= d;
178  m_maxPoint += d;
179  }
180 
182  void expandToMinExtentRelative(PREC p, PREC defaultExtent, PREC eps){
183  ArrayStat<Dim> e = extent();
184  VectorStat<Dim> c = center();
185  typename ArrayStat<Dim>::Index idx;
186  PREC ext = std::abs(e.maxCoeff(&idx)) * p;
187 
188  if( ext < eps ){ // extent of max axis almost zero, set all axis to defaultExtent --> cube
189  ext = defaultExtent;
190  m_minPoint = c - 0.5*ext;
191  m_maxPoint = c + 0.5*ext;
192  }else{
193  for(int i=0;i<Dim;++i){
194  if(i!=idx && std::abs(e(i)) < ext){
195  m_minPoint(i) = c(i) - 0.5*ext;
196  m_maxPoint(i) = c(i) + 0.5*ext;
197  }
198  }
199  }
200  }
201 
203  void expandToMinExtentAbsolute(PREC minExtent){
204  Array3 e = extent();
205  Vector3 c = center();
206 
207  PREC l = 0.5*minExtent;
208  for(int i=0;i<Dim;++i){
209  if(std::abs(e(i)) < minExtent){
210  m_minPoint(i) = c(i) - l;
211  m_maxPoint(i) = c(i) + l;
212  }
213  }
214  }
215 
217  void expandToMinExtentAbsolute(ArrayStat<Dim> minExtent){
218  Array3 e = extent();
219  Vector3 c = center();
220 
221  for(unsigned int i=0;i<Dim;++i){
222  PREC l = minExtent(i);
223  if(std::abs(e(i)) < l){
224  m_minPoint(i) = c(i) - 0.5*l;
225  m_maxPoint(i) = c(i) + 0.5*l;
226  }
227  }
228  }
229 
234  template<bool MoveMax>
235  void expandToMaxExtent(const unsigned int & axis){
236  ApproxMVBB_ASSERTMSG(axis < Dim,"axis >= Dim !");
237  if(!MoveMax){
238  m_minPoint(axis) = std::numeric_limits<PREC>::lowest();
239  }else{
240  m_maxPoint(axis) = std::numeric_limits<PREC>::max();
241  }
242  }
243 
244  void expandToMaxExtent(){
245  m_minPoint.setConstant(std::numeric_limits<PREC>::lowest());
246  m_maxPoint.setConstant(std::numeric_limits<PREC>::max());
247  }
248 
249  inline PREC volume() const {
250  return (m_maxPoint - m_minPoint).prod();
251  }
252 
253  //info about axis aligned bounding box
254  VectorStat<Dim> m_minPoint;
255  VectorStat<Dim> m_maxPoint;
256 };
257 
258 using AABB3d = AABB<3>;
259 using AABB2d = AABB<2>;
260 
261 }
262 
263  #endif
#define ApproxMVBB_ASSERTMSG(condition, message)
An Assert Macro to use within C++ code.
void expand(VectorStat< Dim > d)
Definition: AABB.hpp:175
void expandToMinExtentAbsolute(ArrayStat< Dim > minExtent)
Definition: AABB.hpp:217
void unite(const AABB &box)
Definition: AABB.hpp:108
AABB & unite(const MatrixBase< Derived > &p)
Definition: AABB.hpp:94
VectorStat< Dim > m_minPoint
Definition: AABB.hpp:254
VectorStat< Dim > center()
Definition: AABB.hpp:138
These are some container definitions.
Eigen::Array< Scalar, M, 1 > ArrayStat
AABB & operator+=(const MatrixBase< Derived > &p)
Definition: AABB.hpp:101
static void apply(T *t, const P &p)
Definition: AABB.hpp:32
bool overlaps(const MatrixBase< Derived > &p) const
Definition: AABB.hpp:145
void expandToMaxExtent(const unsigned int &axis)
Definition: AABB.hpp:235
bool overlaps(const AABB &box) const
Definition: AABB.hpp:140
VectorStat< Dim > m_maxPoint
Definition: AABB.hpp:255
static void apply(T *, const P &)
Definition: AABB.hpp:41
AABB & operator+=(const AABB &box)
Definition: AABB.hpp:112
static void apply(T *t, const B &b)
Definition: AABB.hpp:47
static void apply(T *, const B &)
Definition: AABB.hpp:56
void reset()
Definition: AABB.hpp:81
AABB & transform(const AffineTrafo &M)
Definition: AABB.hpp:123
void expandToMinExtentAbsolute(PREC minExtent)
Definition: AABB.hpp:203
Eigen::Array< Scalar, 3, 1 > Array3
static void apply(T *t)
Definition: AABB.hpp:63
AABB(const VectorStat< Dim > &p)
Definition: AABB.hpp:85
bool isEmpty() const
Definition: AABB.hpp:165
AABB operator+(const AABB &box)
Definition: AABB.hpp:117
void expandToMinExtentRelative(PREC p, PREC defaultExtent, PREC eps)
Definition: AABB.hpp:182
Eigen::Matrix< Scalar, 3, 1 > Vector3
bool overlapsSubSpace(const AABB &box, unsigned int fixedAxis) const
Definition: AABB.hpp:149
void expand(PREC d)
Definition: AABB.hpp:169
#define ApproxMVBB_STATIC_ASSERTM(B, COMMENT)
Eigen::Transform< Scalar, 3, Eigen::TransformTraits::Affine > AffineTrafo
#define ApproxMVBB_DEFINE_MATRIX_TYPES
Definition: TypeDefs.hpp:26
ArrayStat< Dim > extent() const
Definition: AABB.hpp:155
AABB(const VectorStat< Dim > &l, const VectorStat< Dim > &u)
Definition: AABB.hpp:87
PREC maxExtent() const
Definition: AABB.hpp:161


asr_approx_mvbb
Author(s): Gassner Nikolai
autogenerated on Mon Jun 10 2019 12:38:08