MRSL DecompUtil Library  0.1
An implementaion of convex decomposition over point cloud
line_segment.h
Go to the documentation of this file.
1 
5 #ifndef LINE_SEGMENT_H
6 #define LINE_SEGMENT_H
7 
10 
16 template <int Dim>
17 class LineSegment : public DecompBase<Dim> {
18  public:
26  LineSegment(const Vecf<Dim> &p1, const Vecf<Dim> &p2) : p1_(p1), p2_(p2) {}
31  void dilate(decimal_t radius) {
32  find_ellipsoid(radius);
33  this->find_polyhedron();
35  }
36 
39  vec_Vecf<Dim> line;
40  line.push_back(p1_);
41  line.push_back(p2_);
42  return line;
43  }
44 
45  protected:
48  if(this->local_bbox_.norm() == 0)
49  return;
50  //**** virtual walls parallel to path p1->p2
51  Vecf<Dim> dir = (p2_ - p1_).normalized();
52  Vecf<Dim> dir_h = Vecf<Dim>::Zero();
53  dir_h(0) = dir(1), dir_h(1) = -dir(0);
54  if (dir_h.norm() == 0) {
55  if(Dim == 2)
56  dir_h << -1, 0;
57  else
58  dir_h << -1, 0, 0;
59  }
60  dir_h = dir_h.normalized();
61 
62  // along x
63  Vecf<Dim> pp1 = p1_ + dir_h * this->local_bbox_(1);
64  Vecf<Dim> pp2 = p1_ - dir_h * this->local_bbox_(1);
65  Vs.add(Hyperplane<Dim>(pp1, dir_h));
66  Vs.add(Hyperplane<Dim>(pp2, -dir_h));
67 
68  // along y
69  Vecf<Dim> pp3 = p2_ + dir * this->local_bbox_(0);
70  Vecf<Dim> pp4 = p1_ - dir * this->local_bbox_(0);
71  Vs.add(Hyperplane<Dim>(pp3, dir));
72  Vs.add(Hyperplane<Dim>(pp4, -dir));
73 
74  // along z
75  if(Dim > 2) {
76  Vecf<Dim> dir_v;
77  dir_v(0) = dir(1) * dir_h(2) - dir(2) * dir_h(1);
78  dir_v(1) = dir(2) * dir_h(0) - dir(0) * dir_h(2);
79  dir_v(2) = dir(0) * dir_h(1) - dir(1) * dir_h(0);
80  Vecf<Dim> pp5 = p1_ + dir_v * this->local_bbox_(2);
81  Vecf<Dim> pp6 = p1_ - dir_v * this->local_bbox_(2);
82  Vs.add(Hyperplane<Dim>(pp5, dir_v));
83  Vs.add(Hyperplane<Dim>(pp6, -dir_v));
84  }
85  }
86 
88  template<int U = Dim>
89  typename std::enable_if<U == 2>::type
90  find_ellipsoid(double offset_x) {
91  const decimal_t f = (p1_ - p2_).norm() / 2;
94  C(0, 0) += offset_x;
95  axes(0) += offset_x;
96 
97  if(axes(0) > 0) {
98  double ratio = axes(1) / axes(0);
99  axes *= ratio;
100  C *= ratio;
101  }
102 
103  const auto Ri = vec2_to_rotation(p2_ - p1_);
104  C = Ri * C * Ri.transpose();
105 
106  Ellipsoid<Dim> E(C, (p1_ + p2_) / 2);
107 
108  auto obs = E.points_inside(this->obs_);
109 
110  auto obs_inside = obs;
111  //**** decide short axes
112  while (!obs_inside.empty()) {
113  const auto pw = E.closest_point(obs_inside);
114  Vecf<Dim> p = Ri.transpose() * (pw - E.d()); // to ellipsoid frame
115  if(p(0) < axes(0))
116  axes(1) = std::abs(p(1)) / std::sqrt(1 - std::pow(p(0) / axes(0), 2));
117  Matf<Dim, Dim> new_C = Matf<Dim, Dim>::Identity();
118  new_C(0, 0) = axes(0);
119  new_C(1, 1) = axes(1);
120  E.C_ = Ri * new_C * Ri.transpose();
121 
122  vec_Vecf<Dim> obs_new;
123  for(const auto &it: obs_inside) {
124  if(1 - E.dist(it) > epsilon_)
125  obs_new.push_back(it);
126  }
127  obs_inside = obs_new;
128  }
129 
130  this->ellipsoid_ = E;
131  }
132 
134  template<int U = Dim>
135  typename std::enable_if<U == 3>::type
136  find_ellipsoid(double offset_x) {
137  const decimal_t f = (p1_ - p2_).norm() / 2;
139  Vecf<Dim> axes = Vecf<Dim>::Constant(f);
140  C(0, 0) += offset_x;
141  axes(0) += offset_x;
142 
143  if(axes(0) > 0) {
144  double ratio = axes(1) / axes(0);
145  axes *= ratio;
146  C *= ratio;
147  }
148 
149  const auto Ri = vec3_to_rotation(p2_ - p1_);
150  C = Ri * C * Ri.transpose();
151 
152  Ellipsoid<Dim> E(C, (p1_ + p2_) / 2);
153  auto Rf = Ri;
154 
155  auto obs = E.points_inside(this->obs_);
156  auto obs_inside = obs;
157  //**** decide short axes
158  while (!obs_inside.empty()) {
159  const auto pw = E.closest_point(obs_inside);
160  Vecf<Dim> p = Ri.transpose() * (pw - E.d()); // to ellipsoid frame
161  const decimal_t roll = atan2(p(2), p(1));
162  Rf = Ri * Quatf(cos(roll / 2), sin(roll / 2), 0, 0);
163  p = Rf.transpose() * (pw - E.d());
164 
165  if(p(0) < axes(0))
166  axes(1) = std::abs(p(1)) / std::sqrt(1 - std::pow(p(0) / axes(0), 2));
167  Matf<Dim, Dim> new_C = Matf<Dim, Dim>::Identity();
168  new_C(0, 0) = axes(0);
169  new_C(1, 1) = axes(1);
170  new_C(2, 2) = axes(1);
171  E.C_ = Rf * new_C * Rf.transpose();
172 
173  vec_Vecf<Dim> obs_new;
174  for(const auto &it: obs_inside) {
175  if(1 - E.dist(it) > epsilon_)
176  obs_new.push_back(it);
177  }
178  obs_inside = obs_new;
179  }
180 
181  //**** reset ellipsoid with old axes(2)
182  C = f * Matf<Dim, Dim>::Identity();
183  C(0, 0) = axes(0);
184  C(1, 1) = axes(1);
185  C(2, 2) = axes(2);
186  E.C_ = Rf * C * Rf.transpose();
187  obs_inside = E.points_inside(obs);
188 
189 
190  while (!obs_inside.empty()) {
191  const auto pw = E.closest_point(obs_inside);
192  Vec3f p = Rf.transpose() * (pw - E.d());
193  decimal_t dd = 1 - std::pow(p(0) / axes(0), 2) -
194  std::pow(p(1) / axes(1), 2);
195  if(dd > 0)
196  axes(2) = std::abs(p(2)) / std::sqrt(dd);
197  Matf<Dim, Dim> new_C = Matf<Dim, Dim>::Identity();
198  new_C(0, 0) = axes(0);
199  new_C(1, 1) = axes(1);
200  new_C(2, 2) = axes(2);
201  E.C_ = Rf * new_C * Rf.transpose();
202 
203  vec_Vecf<Dim> obs_new;
204  for(const auto &it: obs_inside) {
205  if(1 - E.dist(it) > epsilon_)
206  obs_new.push_back(it);
207  }
208  obs_inside = obs_new;
209  }
210 
211  this->ellipsoid_ = E;
212  }
213 
218 };
219 
221 
223 #endif
vec_E< Vecf< N >> vec_Vecf
Vector of Eigen 1D float vector.
Definition: data_type.h:69
Line Segment Class.
Definition: decomp_base.h:18
Vecf< Dim > local_bbox_
Local bounding box along the line segment.
Definition: decomp_base.h:94
Vecf< Dim > p2_
The other end of line segment, input.
Definition: line_segment.h:217
Line Segment Class.
Definition: line_segment.h:17
Polyhedron< Dim > polyhedron_
Output polyhedron.
Definition: decomp_base.h:91
Polyhedron class.
Definition: polyhedron.h:41
Mat2f vec2_to_rotation(const Vec2f &v)
Calculate rotation matrix from a vector (aligned with x-axis)
Definition: geometric_utils.h:20
constexpr decimal_t epsilon_
Compensate for numerical error.
Definition: data_type.h:126
decimal_t dist(const Vecf< Dim > &pt) const
Calculate distance to the center.
Definition: ellipsoid.h:19
Definition: ellipsoid.h:14
void add(const Hyperplane< Dim > &v)
Append Hyperplane.
Definition: polyhedron.h:49
std::enable_if< U==3 >::type find_ellipsoid(double offset_x)
Find ellipsoid in 3D.
Definition: line_segment.h:136
vec_Vecf< Dim > obs_
Obstacles, input.
Definition: decomp_base.h:86
vec_Vecf< Dim > points_inside(const vec_Vecf< Dim > &O) const
Calculate points inside ellipsoid, non-exclusive.
Definition: ellipsoid.h:29
LineSegment()
Simple constructor.
Definition: line_segment.h:20
Vecf< 3 > Vec3f
Eigen 1D float vector of size 3.
Definition: data_type.h:79
Vecf< Dim > closest_point(const vec_Vecf< Dim > &O) const
Find the closest point.
Definition: ellipsoid.h:39
basic geometry utils
Eigen::Matrix< decimal_t, M, N > Matf
MxN Eigen matrix.
Definition: data_type.h:63
void dilate(decimal_t radius)
Infalte the line segment.
Definition: line_segment.h:31
Decomp Base Class.
std::enable_if< U==2 >::type find_ellipsoid(double offset_x)
Find ellipsoid in 2D.
Definition: line_segment.h:90
double decimal_t
Rename the float type used in lib.
Definition: data_type.h:50
Eigen::Quaternion< decimal_t > Quatf
Allias of Eigen::Quaterniond.
Definition: data_type.h:120
Eigen::Matrix< decimal_t, N, 1 > Vecf
Eigen 1D float vector.
Definition: data_type.h:57
Hyperplane class.
Definition: polyhedron.h:13
Ellipsoid< Dim > ellipsoid_
Output ellipsoid.
Definition: decomp_base.h:89
Vecf< Dim > p1_
One end of line segment, input.
Definition: line_segment.h:215
Vecf< Dim > d() const
Get center.
Definition: ellipsoid.h:90
vec_Vecf< Dim > get_line_segment() const
Get the line.
Definition: line_segment.h:38
void add_local_bbox(Polyhedron< Dim > &Vs)
Add the bounding box.
Definition: line_segment.h:47
LineSegment(const Vecf< Dim > &p1, const Vecf< Dim > &p2)
Basic constructor.
Definition: line_segment.h:26