24 #include "Eigen/StdVector" 29 namespace perception {
32 template <
typename T =
double>
35 typedef Eigen::Matrix<T, 2, 1>
Point;
36 typedef std::vector<Point, Eigen::aligned_allocator<Point>>
Polygon;
44 if (delta_x < 0 || !std::isfinite(
k)) {
56 "max_x: %13.10lf max_y: %13.10lf" 57 "min_x: %13.10lf min_y: %13.10lf" 58 "x: %13.10lf y: %13.10lf k %13.10lf") %
85 const Polygon&
polygon()
const {
return polygon_; }
92 std::vector<IntervalOut>* scan_intervals);
93 void ScansCvt(
const IntervalIn& scans_interval,
95 std::vector<std::vector<IntervalOut>>* scans_intervals);
102 void ParsePolygon(
const DirectionMajor dir_major,
const bool disturb =
false);
104 void UpdateAet(std::vector<IntervalOut>* scan_intervals);
106 bool ConvertSegment(
const size_t seg_id, std::pair<int, Edge>* out_edge);
109 Polygon polygon_disturbed_;
110 std::vector<std::vector<bool>> is_singular_;
111 std::vector<std::vector<Segment>> segments_;
113 std::vector<std::vector<double>> ks_;
115 std::vector<std::pair<double, double>> top_segments_;
118 std::vector<std::vector<Edge>> et_;
120 std::pair<size_t, std::vector<Edge>> aet_;
121 double bottom_x_ = 0.0;
123 size_t scans_size_ = 0;
128 template <
typename T>
130 std::numeric_limits<float>::epsilon();
132 template <
typename T>
135 template <
typename T>
139 is_singular_.resize(2);
144 template <
typename T>
147 is_singular_.clear();
152 template <
typename T>
154 std::vector<IntervalOut>* scan_intervals) {
157 auto& is_singular = is_singular_[dir_major];
158 auto& segments = segments_[dir_major];
159 auto& ks = ks_[dir_major];
160 CHECK_EQ(segments.size(), polygon_.size());
161 CHECK_EQ(segments.size(), ks.size());
162 scan_intervals->clear();
163 scan_intervals->reserve(polygon_.size());
164 std::vector<double> nodes;
165 nodes.reserve(polygon_.size());
167 for (
size_t i = 0; i < segments.size(); ++i) {
168 const Segment& segment = segments[i];
169 const Point& low_vertex = segment.first;
170 const Point& high_vertex = segment.second;
171 double high_x = high_vertex[dir_major];
172 double high_y = high_vertex[op_dir_major];
173 double low_x = low_vertex[dir_major];
174 double low_y = low_vertex[op_dir_major];
176 if (std::isfinite(k)) {
177 if ((x >= low_x && x < high_x) || (x <= low_x && x > high_x)) {
179 nodes.push_back(low_y);
180 if (is_singular[i]) {
181 nodes.push_back(low_y);
184 nodes.push_back(low_y + (x - low_x) * k);
190 if (low_y < high_y) {
191 scan_intervals->push_back(
IntervalOut(low_y, high_y));
193 scan_intervals->push_back(
IntervalOut(high_y, low_y));
198 CHECK_EQ(nodes.size() % 2,
static_cast<size_t>(0));
199 std::sort(nodes.begin(), nodes.end());
200 for (
size_t i = 0; i < nodes.size(); i += 2) {
201 scan_intervals->push_back(
IntervalOut(nodes[i], nodes[i + 1]));
205 template <
typename T>
208 const T& step, std::vector<std::vector<IntervalOut>>* scans_intervals) {
209 dir_major_ = dir_major;
213 CHECK_GT(scans_interval.second, scans_interval.first + step);
215 bottom_x_ = scans_interval.first;
216 double top_x = scans_interval.second;
217 scans_size_ =
static_cast<size_t>((top_x - bottom_x_) / step_);
219 top_segments_.clear();
220 top_segments_.reserve(2);
222 ParsePolygon(dir_major,
true);
225 scans_intervals->clear();
226 scans_intervals->resize(scans_size_);
230 (*scans_intervals)[0].reserve(polygon_.size());
232 for (
const auto&
edge : et_[0]) {
233 if (std::isfinite(
edge.k)) {
234 aet_.second.push_back(
edge);
240 std::sort(aet_.second.begin(), aet_.second.end());
241 CHECK_EQ(aet_.second.size() & 1,
static_cast<size_t>(0));
244 for (
size_t i = 0; i < aet_.second.size(); i += 2) {
245 double min_y = aet_.second[i].y;
246 double max_y = aet_.second[i + 1].y;
247 (*scans_intervals)[0].push_back(
IntervalOut(min_y, max_y));
249 for (
size_t i = 1; i < scans_size_; ++i) {
250 UpdateAet(&((*scans_intervals)[i]));
253 if (top_segments_.size()) {
254 scans_intervals->resize(scans_size_ + 1);
255 for (
auto& seg : top_segments_) {
256 double y1 = seg.first;
257 double y2 = seg.second;
258 double min_y = std::min(y1, y2);
259 double max_y = std::max(y1, y2);
260 (*scans_intervals)[scans_size_].push_back(
IntervalOut(min_y, max_y));
265 template <
typename T>
267 for (
auto& pt : polygon_disturbed_) {
268 T&
x = pt[dir_major];
269 double d_x = (x - bottom_x_) / step_;
270 int int_d_x =
static_cast<int>(std::round(d_x));
271 double delta_x = d_x - int_d_x;
274 x =
static_cast<T
>((int_d_x +
s_epsilon_) * step_ + bottom_x_);
276 x =
static_cast<T
>((int_d_x -
s_epsilon_) * step_ + bottom_x_);
282 template <
typename T>
284 const bool disturb) {
285 polygon_disturbed_ = polygon_;
287 DisturbPolygon(dir_major);
290 size_t vertices_size = polygon_disturbed_.size();
291 is_singular_[dir_major].clear();
292 is_singular_[dir_major].reserve(vertices_size);
293 segments_[dir_major].clear();
294 segments_[dir_major].reserve(vertices_size);
295 ks_[dir_major].clear();
296 ks_[dir_major].reserve(vertices_size);
298 auto& is_singular = is_singular_[dir_major];
299 auto& segments = segments_[dir_major];
300 auto& ks = ks_[dir_major];
302 for (
size_t i = 0; i < vertices_size; ++i) {
303 const Point& pre_vertex =
304 polygon_disturbed_[(i + vertices_size - 1) % vertices_size];
305 const Point& vertex = polygon_disturbed_[i];
306 const Point& nex_vertex = polygon_disturbed_[(i + 1) % vertices_size];
307 T pre_x = pre_vertex[dir_major];
308 T
x = vertex[dir_major];
309 T
y = vertex[op_dir_major];
310 T nex_x = nex_vertex[dir_major];
311 T nex_y = nex_vertex[op_dir_major];
314 Segment line_seg(vertex, nex_vertex);
315 double x_diff = nex_x -
x;
316 double y_diff = nex_y -
y;
319 segments.push_back(line_seg);
321 : ks.push_back(y_diff / x_diff);
322 double pre_x_diff = pre_x -
x;
328 is_singular.push_back(
true);
330 pre_x_diff* x_diff > 0 ? is_singular.push_back(
true)
331 : is_singular.push_back(
false);
336 template <
typename T>
338 const auto& segments = segments_[dir_major_];
341 et_.resize(scans_size_);
342 for (
auto& edge_list : et_) {
343 edge_list.reserve(polygon_.size());
347 std::vector<std::pair<int, Edge>> edges;
348 edges.reserve(segments.size());
349 for (
size_t i = 0; i < segments.size(); ++i) {
350 std::pair<int, Edge> out_edge;
351 if (ConvertSegment(i, &(out_edge))) {
352 edges.push_back(out_edge);
359 aet_.second.reserve(segments.size());
360 for (
size_t i = 0; i < edges.size(); ++i) {
361 int x_id = edges[i].first;
363 if (x_id >= static_cast<int>(scans_size_)) {
368 et_[x_id].push_back(edge);
371 Edge active_edge = edge;
372 if (active_edge.
MoveUp(0.0 - active_edge.
x)) {
373 aet_.second.push_back(active_edge);
379 template <
typename T>
381 size_t x_id = aet_.first + 1;
382 CHECK_LT(x_id, et_.size());
384 scan_intervals->clear();
385 scan_intervals->reserve(polygon_.size());
388 size_t valid_edges_num = aet_.second.size();
389 size_t invalid_edges_num = 0;
390 for (
auto&
edge : aet_.second) {
391 if (!
edge.MoveUp(step_)) {
399 size_t new_edges_num = 0;
400 for (
const auto&
edge : et_[x_id]) {
401 if (std::isfinite(
edge.k)) {
404 aet_.second.push_back(
edge);
409 CHECK_EQ(valid_edges_num & 1, static_cast<size_t>(0))
411 "valid edges num: %d x: %lf bottom_x: %lf \n vertices num: %d " 413 valid_edges_num % (x_id * step_ + bottom_x_) % bottom_x_ %
415 << aet_.second[0] <<
"\n" 416 << aet_.second[1] <<
"\n" 417 << aet_.second[2] <<
"\n" 421 if (invalid_edges_num != 0 || new_edges_num != 0) {
422 std::sort(aet_.second.begin(), aet_.second.end());
424 aet_.second.resize(valid_edges_num);
426 for (
size_t i = 0; i < aet_.second.size(); i += 2) {
428 double min_y = aet_.second[i].y;
429 double max_y = aet_.second[i + 1].y;
430 scan_intervals->push_back(
IntervalOut(min_y, max_y));
434 template <
typename T>
436 std::pair<int, Edge>* out_edge) {
437 const auto& segments = segments_[dir_major_];
438 const auto& ks = ks_[dir_major_];
440 CHECK_LT(seg_id, segments.size());
441 Segment segment = segments[seg_id];
442 double k = ks[seg_id];
443 const Point& low_vertex = segment.first;
444 const Point& high_vertex = segment.second;
445 if (low_vertex[dir_major_] > high_vertex[dir_major_]) {
446 std::swap(segment.first, segment.second);
450 int& x_id = out_edge->first;
451 const Point& min_vertex = segment.first;
452 double min_x = min_vertex[dir_major_] - bottom_x_;
453 double min_y = min_vertex[op_dir_major_];
454 x_id =
static_cast<int>(std::ceil(min_x / step_));
455 double min_x_ceil = x_id * step_;
459 edge.
max_x = segment.second[dir_major_] - bottom_x_;
460 edge.
max_y = segment.second[op_dir_major_];
463 if (std::isfinite(edge.
k)) {
464 edge.
y = min_y + (edge.
x -
min_x) * edge.
k;
468 if (edge.
y > edge.
max_y) {
469 std::swap(edge.
y, edge.
max_y);
475 if (static_cast<size_t>(x_id) >= scans_size_) {
476 std::pair<double, double> seg(low_vertex[op_dir_major_],
477 high_vertex[op_dir_major_]);
478 top_segments_.push_back(seg);
481 if (std::isfinite(edge.
k) && edge.
max_x < edge.
x) {
PolygonScanCvter()=default
double y
Definition: polygon_scan_cvter.h:71
Definition: polygon_scan_cvter.h:75
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
double min_y
Definition: polygon_scan_cvter.h:68
const Polygon & polygon() const
Definition: polygon_scan_cvter.h:85
static const double s_epsilon_
Definition: polygon_scan_cvter.h:97
void Reset()
Definition: polygon_scan_cvter.h:145
Definition: segment_graph.h:47
T abs(const T &x)
Definition: misc.h:48
std::pair< Point, Point > Segment
Definition: polygon_scan_cvter.h:39
double max_y
Definition: polygon_scan_cvter.h:65
DirectionMajor
Definition: polygon_scan_cvter.h:75
double min_x
Definition: polygon_scan_cvter.h:67
static DirectionMajor OppositeDirection(const DirectionMajor dir_major)
Definition: polygon_scan_cvter.h:77
bool operator<(const Edge &other) const
Definition: polygon_scan_cvter.h:42
void ScansCvt(const IntervalIn &scans_interval, const DirectionMajor dir_major, const T &step, std::vector< std::vector< IntervalOut >> *scans_intervals)
Definition: polygon_scan_cvter.h:206
Definition: polygon_scan_cvter.h:33
static const double s_inf_
Definition: polygon_scan_cvter.h:98
double max_x
Definition: polygon_scan_cvter.h:64
virtual ~PolygonScanCvter()=default
double x
Definition: polygon_scan_cvter.h:70
std::vector< Point, Eigen::aligned_allocator< Point > > Polygon
Definition: polygon_scan_cvter.h:36
void ScanCvt(const T &scan_loc, DirectionMajor dir_major, std::vector< IntervalOut > *scan_intervals)
Definition: polygon_scan_cvter.h:153
std::pair< T, T > IntervalIn
Definition: polygon_scan_cvter.h:37
Definition: polygon_scan_cvter.h:75
std::pair< double, double > IntervalOut
Definition: polygon_scan_cvter.h:38
Eigen::Matrix< T, 2, 1 > Point
Definition: polygon_scan_cvter.h:35
void Init(const Polygon &polygon)
Definition: polygon_scan_cvter.h:136
double k
Definition: polygon_scan_cvter.h:72
Definition: polygon_scan_cvter.h:41
bool MoveUp(double delta_x)
Definition: polygon_scan_cvter.h:43
friend std::ostream & operator<<(std::ostream &out, const Edge &edge)
Definition: polygon_scan_cvter.h:54