ed
convex_hull_calc.cpp
Go to the documentation of this file.
1 #include "ed/convex_hull_calc.h"
2 
3 #include <opencv2/imgproc/imgproc.hpp>
4 
5 namespace ed
6 {
7 
8 namespace convex_hull
9 {
10 
11 // ----------------------------------------------------------------------------------------------------
12 
21 void create(const std::vector<geo::Vec2f>& points, float z_min, float z_max, ConvexHull& chull, geo::Pose3D& pose)
22 {
23  cv::Mat_<cv::Vec2f> points_2d(1, points.size());
24  for(unsigned int i = 0; i < points.size(); ++i)
25  points_2d.at<cv::Vec2f>(i) = cv::Vec2f(points[i].x, points[i].y);
26 
27  pose = geo::Pose3D::identity();
28 
29  pose.t.z = (z_min + z_max) / 2;
30 
31  std::vector<int> chull_indices;
32  cv::convexHull(points_2d, chull_indices);
33 
34  chull.z_min = z_min - pose.t.z;
35  chull.z_max = z_max - pose.t.z;
36 
37  geo::Vec2f xy_min(1e9, 1e9);
38  geo::Vec2f xy_max(-1e9, -1e9);
39 
40  chull.points.clear();
41  for(unsigned int i = 0; i < chull_indices.size(); ++i)
42  {
43  const cv::Vec2f& p_cv = points_2d.at<cv::Vec2f>(chull_indices[i]);
44  geo::Vec2f p(p_cv[0], p_cv[1]);
45 
46  chull.points.push_back(p);
47 
48  xy_min.x = std::min(xy_min.x, p.x);
49  xy_min.y = std::min(xy_min.y, p.y);
50 
51  xy_max.x = std::max(xy_max.x, p.x);
52  xy_max.y = std::max(xy_max.y, p.y);
53  }
54 
55  // Average segment position
56  pose.t.x = (xy_min.x + xy_max.x) / 2;
57  pose.t.y = (xy_min.y + xy_max.y) / 2;
58 
59  // Move all points to the pose frame
60  for(unsigned int i = 0; i < chull.points.size(); ++i)
61  {
62  geo::Vec2f& p = chull.points[i];
63  p.x -= pose.t.x;
64  p.y -= pose.t.y;
65  }
66 
67  // Calculate normals and edges
69 
70  // Calculate area
71  calculateArea(chull);
72 }
73 
74 // ----------------------------------------------------------------------------------------------------
75 
83 void createAbsolute(const std::vector<geo::Vec2f>& points, float z_min, float z_max, ConvexHull& chull)
84 {
85  cv::Mat_<cv::Vec2f> points_2d(1, points.size());
86  for(unsigned int i = 0; i < points.size(); ++i)
87  points_2d.at<cv::Vec2f>(i) = cv::Vec2f(points[i].x, points[i].y);
88 
89  chull.z_min = z_min;
90  chull.z_max = z_max;
91 
92  std::vector<int> chull_indices;
93  cv::convexHull(points_2d, chull_indices);
94 
95  chull.points.resize(chull_indices.size());
96  for(unsigned int i = 0; i < chull_indices.size(); ++i)
97  {
98  const cv::Vec2f& p_cv = points_2d.at<cv::Vec2f>(chull_indices[i]);
99  chull.points[i] = geo::Vec2f(p_cv[0], p_cv[1]);
100  }
101 
102  // Calculate normals and edges
104 
105  // Calculate area
106  calculateArea(chull);
107 }
108 
109 // ----------------------------------------------------------------------------------------------------
110 
112 {
113  chull.edges.resize(chull.points.size());
114  chull.normals.resize(chull.points.size());
115 
116  for(unsigned int i = 0; i < chull.points.size(); ++i)
117  {
118  unsigned int j = (i + 1) % chull.points.size();
119 
120  const geo::Vec2f& p1 = chull.points[i];
121  const geo::Vec2f& p2 = chull.points[j];
122 
123  // Calculate edge
124  geo::Vec2f e = p2 - p1;
125  chull.edges[i] = e;
126 
127  // Calculate normal
128  chull.normals[i] = geo::Vec2f(e.y, -e.x).normalized();
129  }
130 }
131 
132 // ----------------------------------------------------------------------------------------------------
133 
144 bool collide(const ConvexHull& c1, const geo::Vector3& pos1,
145  const ConvexHull& c2, const geo::Vector3& pos2,
146  float xy_padding, float z_padding)
147 {
148  if (c1.points.size() < 3 || c2.points.size() < 3)
149  return false;
150 
151  float z_diff = pos2.z - pos1.z;
152 
153  if (c1.z_max < (c2.z_min + z_diff - 2 * z_padding) || c2.z_max < (c1.z_min - z_diff - 2 * z_padding))
154  return false;
155 
156  geo::Vec2f pos_diff(pos2.x - pos1.x, pos2.y - pos1.y);
157 
158  for(unsigned int i = 0; i < c1.points.size(); ++i)
159  {
160  const geo::Vec2f& p1 = c1.points[i];
161  const geo::Vec2f& n = c1.normals[i];
162 
163  // Calculate min and max projection of c1
164  float min1 = n.dot(c1.points[0] - p1);
165  float max1 = min1;
166  for(unsigned int k = 1; k < c1.points.size(); ++k)
167  {
168  // Calculate projection
169  float p = n.dot(c1.points[k] - p1);
170  min1 = std::min(min1, p);
171  max1 = std::max(max1, p);
172  }
173 
174  // Apply padding to both sides
175  min1 -= xy_padding;
176  max1 += xy_padding;
177 
178  // Calculate p1 in c2's frame
179  geo::Vec2f p1_c2 = p1 - pos_diff;
180 
181  // If this bool stays true, there is definitely no collision
182  bool no_collision = true;
183 
184  // True if projected points are found below c1's bounds
185  bool below = false;
186 
187  // True if projected points are found above c1's bounds
188  bool above = false;
189 
190  // Check if c2's points overlap with c1's bounds
191  for(unsigned int k = 0; k < c2.points.size(); ++k)
192  {
193  // Calculate projection on p1's normal
194  float p = n.dot(c2.points[k] - p1_c2);
195 
196  below = below || (p < max1);
197  above = above || (p > min1);
198 
199  if (below && above)
200  {
201  // There is overlap with c1's bound, so we may have a collision
202  no_collision = false;
203  break;
204  }
205  }
206 
207  if (no_collision)
208  // definitely no collision
209  return false;
210  }
211 
212  return true;
213 }
214 
215 // ----------------------------------------------------------------------------------------------------
216 
222 {
223  c.area = 0;
224  for(unsigned int i = 0; i < c.points.size(); ++i)
225  {
226  unsigned int j = (i + 1) % c.points.size();
227 
228  const geo::Vec2f& p1 = c.points[i];
229  const geo::Vec2f& p2 = c.points[j];
230 
231  c.area += 0.5 * (p1.x * p2.y - p2.x * p1.y);
232  }
233 }
234 
235 // ----------------------------------------------------------------------------------------------------
236 
237 }
238 
239 }
geo::Vector3::y
const real & y() const
convex_hull_calc.h
ed::ConvexHull::z_min
float z_min
Definition: convex_hull.h:16
ed::ConvexHull
Definition: convex_hull.h:11
ed::convex_hull::calculateEdgesAndNormals
void calculateEdgesAndNormals(ConvexHull &chull)
Definition: convex_hull_calc.cpp:111
ed::convex_hull::create
void create(const std::vector< geo::Vec2f > &points, float z_min, float z_max, ConvexHull &chull, geo::Pose3D &pose)
create fill a ConvexHull and put its origin in the middle of the Convexhull
Definition: convex_hull_calc.cpp:21
geo::Vec2T::y
T y
geo::Transform3T::identity
static Transform3T identity()
std::vector
std::vector::size
T size(T... args)
geo::Vec2T::dot
T dot(const Vec2T &v) const
geo::Vec2T::x
T x
geo::Transform3T
geo::Vec2f
Vec2T< float > Vec2f
geo::Vec3T::y
T y
ed::convex_hull::collide
bool collide(const ConvexHull &c1, const geo::Vector3 &pos1, const ConvexHull &c2, const geo::Vector3 &pos2, float xy_padding=0, float z_padding=0)
collide Check of two ConvexHull collide with padding in xy and in z.
Definition: convex_hull_calc.cpp:144
ed::ConvexHull::normals
std::vector< geo::Vec2f > normals
Definition: convex_hull.h:15
geo::Transform3T::t
Vec3T< T > t
geo::Vector3
geo::Vector3::z
const real & z() const
std::min
T min(T... args)
ed::ConvexHull::edges
std::vector< geo::Vec2f > edges
Definition: convex_hull.h:14
geo::Vector3::x
const real & x() const
geo::Vec3T::z
T z
ed
Definition: convex_hull.h:8
ed::convex_hull::createAbsolute
void createAbsolute(const std::vector< geo::Vec2f > &points, float z_min, float z_max, ConvexHull &chull)
createAbsolute fill a ConvexHull with its origin in map frame.
Definition: convex_hull_calc.cpp:83
std::max
T max(T... args)
c
void c()
ed::ConvexHull::z_max
float z_max
Definition: convex_hull.h:16
ed::convex_hull::calculateArea
void calculateArea(ConvexHull &c)
calculateArea calculate the area of the ConvexHull in xy-plane.
Definition: convex_hull_calc.cpp:221
geo::Vec3T::x
T x
geo::Vec2T
ed::ConvexHull::points
std::vector< geo::Vec2f > points
Definition: convex_hull.h:13