22 #include "Eigen/Dense" 25 namespace perception {
28 template <
class CLOUD_IN_TYPE,
class CLOUD_OUT_TYPE>
32 points_.reserve(1000.0);
33 polygon_indices_.reserve(1000.0);
38 CLOUD_OUT_TYPE* out_polygon) {
40 if (!GetConvexHullMonotoneChain(out_polygon)) {
41 return MockConvexHull(out_polygon);
47 const float& distance_above_ground_thres,
48 CLOUD_OUT_TYPE* out_polygon) {
49 CLOUD_IN_TYPE in_cloud_without_ground;
50 in_cloud_without_ground.reserve(in_cloud.size());
51 for (std::size_t
id = 0;
id < in_cloud.size(); ++id) {
53 if (in_cloud.points_height(
id) >= distance_above_ground_thres) {
54 in_cloud_without_ground.push_back(in_cloud[
id]);
57 if (in_cloud_without_ground.empty()) {
60 SetPoints(in_cloud_without_ground);
61 if (!GetConvexHullMonotoneChain(out_polygon)) {
62 return MockConvexHull(out_polygon);
70 const CLOUD_IN_TYPE& in_cloud,
const float& distance_above_ground_thres,
71 const float& distance_beneath_head_thres, CLOUD_OUT_TYPE* out_polygon) {
72 CLOUD_IN_TYPE in_cloud_without_ground_and_head;
73 in_cloud_without_ground_and_head.reserve(in_cloud.size());
74 for (std::size_t
id = 0;
id < in_cloud.size(); ++id) {
76 if (in_cloud.points_height(
id) == FLT_MAX ||
77 (in_cloud.points_height(
id) >= distance_above_ground_thres &&
78 in_cloud.points_height(
id) <= distance_beneath_head_thres)) {
79 in_cloud_without_ground_and_head.push_back(in_cloud[
id]);
82 if (in_cloud_without_ground_and_head.empty()) {
85 SetPoints(in_cloud_without_ground_and_head);
86 if (!GetConvexHullMonotoneChain(out_polygon)) {
87 return MockConvexHull(out_polygon);
95 void SetPoints(
const CLOUD_IN_TYPE& in_cloud);
97 bool MockConvexHull(CLOUD_OUT_TYPE* out_polygon);
99 bool GetConvexHullMonotoneChain(CLOUD_OUT_TYPE* out_polygon);
101 bool IsCounterClockWise(
const Eigen::Vector2d& p1,
const Eigen::Vector2d& p2,
102 const Eigen::Vector2d& p3,
const double& eps) {
103 Eigen::Vector2d p12 = p2 - p1;
104 Eigen::Vector2d p13 = p3 - p1;
105 return (p12(0) * p13(1) - p12(1) * p13(0) > eps);
109 std::vector<Eigen::Vector2d> points_;
110 std::vector<std::size_t> polygon_indices_;
111 const CLOUD_IN_TYPE* in_cloud_;
114 template <
class CLOUD_IN_TYPE,
class CLOUD_OUT_TYPE>
116 const CLOUD_IN_TYPE& in_cloud) {
117 points_.resize(in_cloud.size());
118 for (std::size_t i = 0; i < points_.size(); ++i) {
119 points_[i] << in_cloud[i].x, in_cloud[i].y;
121 in_cloud_ = &in_cloud;
124 template <
class CLOUD_IN_TYPE,
class CLOUD_OUT_TYPE>
126 CLOUD_OUT_TYPE* out_polygon) {
127 if (in_cloud_->size() == 0) {
130 out_polygon->resize(4);
131 Eigen::Matrix<double, 3, 1> maxv;
132 Eigen::Matrix<double, 3, 1> minv;
133 maxv << in_cloud_->at(0).x, in_cloud_->at(0).y, in_cloud_->at(0).z;
135 for (std::size_t i = 1; i < in_cloud_->size(); ++i) {
136 maxv(0) = std::max<double>(maxv(0), in_cloud_->at(i).x);
137 maxv(1) = std::max<double>(maxv(1), in_cloud_->at(i).y);
138 maxv(2) = std::max<double>(maxv(2), in_cloud_->at(i).z);
140 minv(0) = std::min<double>(minv(0), in_cloud_->at(i).x);
141 minv(1) = std::min<double>(minv(1), in_cloud_->at(i).y);
142 minv(2) = std::min<double>(minv(2), in_cloud_->at(i).z);
145 static const double eps = 1e-3;
146 for (std::size_t i = 0; i < 3; ++i) {
147 if (maxv(i) - minv(i) < eps) {
153 out_polygon->at(0).x =
static_cast<float>(minv(0));
154 out_polygon->at(0).y =
static_cast<float>(minv(1));
155 out_polygon->at(0).z =
static_cast<float>(minv(2));
157 out_polygon->at(1).x =
static_cast<float>(maxv(0));
158 out_polygon->at(1).y =
static_cast<float>(minv(1));
159 out_polygon->at(1).z =
static_cast<float>(minv(2));
161 out_polygon->at(2).x =
static_cast<float>(maxv(0));
162 out_polygon->at(2).y =
static_cast<float>(maxv(1));
163 out_polygon->at(2).z =
static_cast<float>(minv(2));
165 out_polygon->at(3).x =
static_cast<float>(minv(0));
166 out_polygon->at(3).y =
static_cast<float>(maxv(1));
167 out_polygon->at(3).z =
static_cast<float>(minv(2));
171 template <
class CLOUD_IN_TYPE,
class CLOUD_OUT_TYPE>
173 CLOUD_OUT_TYPE* out_polygon) {
174 if (points_.size() < 3) {
178 std::vector<std::size_t> sorted_indices(points_.size());
179 std::iota(sorted_indices.begin(), sorted_indices.end(), 0);
181 static const double eps = 1e-9;
182 std::sort(sorted_indices.begin(), sorted_indices.end(),
183 [&](
const std::size_t& lhs,
const std::size_t& rhs) {
184 double dx = points_[lhs](0) - points_[rhs](0);
188 return points_[lhs](1) < points_[rhs](1);
192 polygon_indices_.clear();
193 polygon_indices_.reserve(points_.size());
195 std::size_t size2 = points_.size() * 2;
196 for (std::size_t i = 0; i < size2; ++i) {
197 if (i == points_.size()) {
200 const std::size_t& idx =
201 sorted_indices[(i < points_.size()) ? i : (size2 - 1 - i)];
202 const auto& point = points_[idx];
203 while (count > last_count &&
204 !IsCounterClockWise(points_[polygon_indices_[count - 2]],
205 points_[polygon_indices_[count - 1]], point,
207 polygon_indices_.pop_back();
210 polygon_indices_.push_back(idx);
214 polygon_indices_.pop_back();
218 out_polygon->clear();
219 out_polygon->resize(polygon_indices_.size());
220 float min_z =
static_cast<float>(in_cloud_->at(0).z);
221 for (std::size_t
id = 0;
id < in_cloud_->size(); ++id) {
222 min_z = std::min<float>(
static_cast<float>(in_cloud_->at(
id).z), min_z);
224 for (std::size_t i = 0; i < polygon_indices_.size(); ++i) {
225 out_polygon->at(i).x =
static_cast<float>(points_[polygon_indices_[i]](0));
226 out_polygon->at(i).y =
static_cast<float>(points_[polygon_indices_[i]](1));
227 out_polygon->at(i).z = min_z;
bool GetConvexHull(const CLOUD_IN_TYPE &in_cloud, CLOUD_OUT_TYPE *out_polygon)
Definition: convex_hull_2d.h:37
bool GetConvexHullWithoutGround(const CLOUD_IN_TYPE &in_cloud, const float &distance_above_ground_thres, CLOUD_OUT_TYPE *out_polygon)
Definition: convex_hull_2d.h:46
T abs(const T &x)
Definition: misc.h:48
Definition: convex_hull_2d.h:29
~ConvexHull2D()
Definition: convex_hull_2d.h:35
ConvexHull2D()
Definition: convex_hull_2d.h:31
bool GetConvexHullWithoutGroundAndHead(const CLOUD_IN_TYPE &in_cloud, const float &distance_above_ground_thres, const float &distance_beneath_head_thres, CLOUD_OUT_TYPE *out_polygon)
Definition: convex_hull_2d.h:69