MinAreaRectangle.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_MinAreaRectangle_hpp
11 #define ApproxMVBB_MinAreaRectangle_hpp
12 
13 #include <string>
14 #include <vector>
15 
17 
18 #include ApproxMVBB_TypeDefs_INCLUDE_FILE
20 #include ApproxMVBB_AssertionDebug_INCLUDE_FILE
21 
25 
26 namespace ApproxMVBB{
31 public:
32  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
34 
36 
41  template<typename Derived>
42  MinAreaRectangle(const MatrixBase<Derived> & points)
43  : m_p(points), m_convh(m_p) {
44  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,2, Eigen::Dynamic)
45  ApproxMVBB_ASSERTMSG( m_p.data() == points.derived().data() ," You store a temporary in a Ref<> which works here, but do you really want this?")
46  }
47 
48  struct Box2d {
49  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
50  inline void reset() {
51  m_p.setZero();
52  m_u.setZero();
53  m_v.setZero();
54  m_area = 0.0;
55  m_uL = 1.0;
56  m_vL = 1.0;
57  }
61 
62  PREC m_uL = 0.0;
63  PREC m_vL = 0.0;
64 
65  PREC m_area = 0.0;
66  };
67 
68  inline const Box2d &
70  return m_minBox;
71  }
72 
73 
74  void compute();
75 
76 private:
77 
79 
80  void computeRectangle();
81 
82  struct Caliper {
83  unsigned int m_idx = 0; // index in m_hullIdx
84  unsigned int m_ptIdx = 0; // index in m_p
85  PREC m_currAngle = 0.0;
86  };
87 
88  inline void adjustRectangle(){
89 
90  // The rectangle might be a slight parallelogram due to numerics
91  // |-l---*
92  // * +++++++=================+
93  // | + | | +
94  // h + | <-v Rect | +
95  // | + | | +
96  // - +=================+++++++
97  // p u
98 
99  PREC uNorm = m_minBox.m_u.norm();
100  PREC vNorm = m_minBox.m_v.norm();
101 
102  // Normalize u direction (if u close to zero -> this becomes not finite)
103  Vector2 uN = m_minBox.m_u.array() / uNorm;
104  Vector2 vN = m_minBox.m_v.array() / vNorm;
105 
106  bool uF = uN.allFinite();
107  bool vF = vN.allFinite();
108 
109  if(uF && vF){
110 
111  // make orthogonal (x axis is u)
112  Vector2 uNT;
113  uNT(0) = -uN(1);
114  uNT(1) = uN(0);
115 
116  PREC h = uNT.dot(m_minBox.m_v);
117  PREC l = uN.dot (m_minBox.m_v);
118 
119  if(l>=0.0){
120  m_minBox.m_uL = uNorm + l;
121  }else{
122  m_minBox.m_uL = uNorm - l;
123  m_minBox.m_p += uN*l; // move start point back
124  }
125 
126  // if v vector pointed downwards (negative h)
127  if( h<0 ){
128  // invert uNT (and switch u,v)
129  uNT *= -1.0;
130  m_minBox.m_u = uNT;
131  m_minBox.m_v = uN;
132  m_minBox.m_vL = m_minBox.m_uL;
133  m_minBox.m_uL = -h;
134  }else{
135  m_minBox.m_vL = h;
136  m_minBox.m_u = uN;
137  m_minBox.m_v = uNT;
138  }
139 
140  }else if(uF && !vF){
141  // set u to normalized
142  m_minBox.m_u = uN;
143  // adjust v direction
144  m_minBox.m_v(0) = -uN(1);
145  m_minBox.m_v(1) = uN(0);
146 
147  m_minBox.m_uL = uNorm;
148  m_minBox.m_vL = 0.0;
149 
150  }else if(!uF && vF){
151  // set v to normalized
152  m_minBox.m_v = vN;
153 
154  // adjust u direction
155  m_minBox.m_u(0) = -vN(1);
156  m_minBox.m_u(1) = vN(0);
157 
158  m_minBox.m_uL = 0.0;
159  m_minBox.m_vL = vNorm;
160  }else{
161  // adjust both directions
162  m_minBox.m_u(0) = 1.0; m_minBox.m_u(1) = 0.0;
163  m_minBox.m_v(0) = 0.0; m_minBox.m_v(1) = 1.0;
164  m_minBox.m_uL = 0.0; m_minBox.m_vL = 0.0;
165  }
166 
167  }
168 
169  inline void updateCalipers(PREC edgeAngle, Caliper (&c)[4]) {
170 
171  updateAngles(edgeAngle, c);
172  for(unsigned char i=0; i<4; i++) {
173  findVertex(c[i]);
174  }
175 
176  }
177 
178  //determine caliper angles according to the box given with c[0].m_currAngle = edgeAngle;
179  inline void updateAngles(PREC edgeAngle, Caliper (&c)[4]) {
180  c[0].m_currAngle = AngleFunctions::mapTo2Pi(edgeAngle);
181  c[1].m_currAngle = AngleFunctions::mapTo2Pi(c[0].m_currAngle + 0.5*M_PI);
182  c[2].m_currAngle = AngleFunctions::mapTo2Pi(c[1].m_currAngle + 0.5*M_PI);
183  c[3].m_currAngle = AngleFunctions::mapTo2Pi(c[2].m_currAngle + 0.5*M_PI);
184 
185  // std::cout << "caliper 1 angle:" << c[0].m_currAngle << std::endl;
186  // std::cout << "caliper 2 angle:" << c[1].m_currAngle << std::endl;
187  // std::cout << "caliper 3 angle:" << c[2].m_currAngle << std::endl;
188  // std::cout << "caliper 4 angle:" << c[3].m_currAngle << std::endl;
189  }
190 
191  // determine the vertex v for which the edge angle is greater than c.m_currAngle
192  // the find algroithm starts at c.m_idx
193  void findVertex(Caliper & c);
194 
195  void getBox(Caliper (&c)[4], Box2d & box);
196 
197 
198  std::vector<unsigned int> m_hullIdx;
199 
200  std::vector<PREC> m_angles;
202  const MatrixRef<const Matrix2Dyn> m_p;
203 
205 
206 };
207 
208 }
209 #endif
#define ApproxMVBB_ASSERTMSG(condition, message)
An Assert Macro to use within C++ code.
Vector2 m_p
first corner x = m_p0 + m_u*m_uL * u + m_v*m_vL * v , u,v in [0,1]
These are some container definitions.
Vector2 m_u
vector of first side (x-Axis) (normalized)
#define APPROXMVBB_EXPORT
Definition: Platform.hpp:60
void updateCalipers(PREC edgeAngle, Caliper(&c)[4])
EIGEN_MAKE_ALIGNED_OPERATOR_NEW ApproxMVBB_DEFINE_MATRIX_TYPES ApproxMVBB_DEFINE_POINTS_CONFIG_TYPES MinAreaRectangle(const MatrixBase< Derived > &points)
void updateAngles(PREC edgeAngle, Caliper(&c)[4])
#define ApproxMVBB_DEFINE_POINTS_CONFIG_TYPES
Eigen::Matrix< Scalar, 2, 1 > Vector2
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void reset()
const MatrixRef< const Matrix2Dyn > m_p
#define ApproxMVBB_DEFINE_MATRIX_TYPES
Definition: TypeDefs.hpp:26
MyMatrix::Vector2< unsigned int > Vector2U
Vector2 m_v
vector of second side (y-Axis) (normalized)
std::vector< unsigned int > m_hullIdx


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