├── data
├── map.pgm
└── basement.png
├── result
├── result.gif
├── basement_path.png
├── basement_contour.png
└── basement_decomposition.png
├── CMakeLists.txt
├── README.md
├── include
├── tcd.h
├── visibility_polygon.h
├── weakly_monotone.h
├── cgal_definitions.h
├── bcd.h
├── cgal_comm.h
├── decomposition.h
├── sweep.h
├── visibility_graph.h
├── graph_base.h
├── coverage_planner.h
└── graph_base_impl.h
└── src
├── tcd.cc
├── weakly_monotone.cc
├── visibility_polygon.cc
├── decomposition.cc
├── cgal_comm.cc
├── visibility_graph.cc
├── sweep.cc
├── bcd.cc
└── main.cpp
/data/map.pgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/data/map.pgm
--------------------------------------------------------------------------------
/data/basement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/data/basement.png
--------------------------------------------------------------------------------
/result/result.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/result/result.gif
--------------------------------------------------------------------------------
/result/basement_path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/result/basement_path.png
--------------------------------------------------------------------------------
/result/basement_contour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/result/basement_contour.png
--------------------------------------------------------------------------------
/result/basement_decomposition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RicheyHuang/CoveragePlanner/HEAD/result/basement_decomposition.png
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 | project(CoveragePlanner)
3 |
4 | set(CMAKE_CXX_STANDARD 14)
5 | set(CMAKE_BUILD_TYPE Release)
6 |
7 | find_package(Eigen3 REQUIRED)
8 | find_package(OpenCV 4 REQUIRED)
9 | find_package(CGAL QUIET COMPONENTS Core)
10 |
11 | include_directories(${EIGEN_INCLUDE_DIRS})
12 | include_directories(${OpenCV_INCLUDE_DIRS})
13 | include_directories(${CGAL_INCLUDE_DIRS})
14 |
15 | file(GLOB_RECURSE srcs "src/*.cc" "src/*.cpp")
16 | file(GLOB_RECURSE hdrs "include/*.h")
17 |
18 | message("find source files: ${srcs}")
19 | message("find headers: ${hdrs}")
20 |
21 | include_directories(include)
22 |
23 | add_executable(CoveragePlanner ${srcs} ${hdrs})
24 |
25 | target_link_libraries(CoveragePlanner
26 | ${OpenCV_LIBS}
27 | CGAL::CGAL
28 | CGAL::CGAL_Core
29 | )
30 |
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CoveragePlanner
2 |
3 | **Dependencies:**
4 |
5 | CGAL 5.0
6 |
7 | OpenCV 4.0
8 |
9 | Eigen 3.0
10 |
11 | **demo:**
12 |
13 | 
14 |
15 | **original pgm map:**
16 |
17 | 
18 |
19 | **acquire polygon boundary and obstacles:**
20 |
21 | 
22 |
23 | **boustrophedon cellular decomposition:**
24 |
25 | 
26 |
27 | **path planning by solving TSP:**
28 |
29 | 
30 |
--------------------------------------------------------------------------------
/include/tcd.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_TCD_H_
21 | #define COVERAGEPLANNER_TCD_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | // Wrapper functions to interface trapezoidal decomposition (TCD).
26 | namespace polygon_coverage_planning {
27 |
28 | std::vector computeTCD(const PolygonWithHoles& polygon_in,
29 | const Direction_2& dir);
30 |
31 | } // namespace polygon_coverage_planning
32 |
33 | #endif // COVERAGEPLANNER_TCD_H_
34 |
--------------------------------------------------------------------------------
/include/visibility_polygon.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_VISIBILITY_POLYGON_H_
21 | #define COVERAGEPLANNER_VISIBILITY_POLYGON_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | namespace polygon_coverage_planning {
26 |
27 | // Compute the visibility polygon given a point inside a strictly simple
28 | // polygon. Francisc Bungiu, Michael Hemmer, John Hershberger, Kan Huang, and
29 | // Alexander Kröller. Efficient computation of visibility polygons. CoRR,
30 | // abs/1403.3905, 2014.
31 | bool computeVisibilityPolygon(const PolygonWithHoles& pwh,
32 | const Point_2& query_point,
33 | Polygon_2* visibility_polygon);
34 |
35 | } // namespace polygon_coverage_planning
36 |
37 | #endif // COVERAGEPLANNER_VISIBILITY_POLYGON_H_
38 |
--------------------------------------------------------------------------------
/include/weakly_monotone.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_WEAKLY_MONOTONE_H_
21 | #define COVERAGEPLANNER_WEAKLY_MONOTONE_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | namespace polygon_coverage_planning {
26 |
27 | // Check whether polygon 'in' is weakly monotone perpendicular to 'x_axis'.
28 | bool isWeaklyMonotone(const Polygon_2& in, const Line_2& x_axis);
29 | // For all edges check whether polygon 'in' is weakly monotone perpendicular to
30 | // that edge.
31 | std::vector getAllSweepableEdgeDirections(const Polygon_2& in);
32 |
33 | VertexConstCirculator findSouth(const Polygon_2& in, const Line_2& x_axis);
34 | VertexConstCirculator findNorth(const Polygon_2& in, const Line_2& x_axis);
35 |
36 | } // namespace polygon_coverage_planning
37 |
38 | #endif // COVERAGEPLANNER_WEAKLY_MONOTONE_H_
39 |
--------------------------------------------------------------------------------
/src/tcd.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #include "cgal_comm.h"
21 | #include "cgal_definitions.h"
22 | #include "tcd.h"
23 |
24 | #include
25 |
26 | namespace polygon_coverage_planning {
27 |
28 | std::vector computeTCD(const PolygonWithHoles& polygon_in,
29 | const Direction_2& dir) {
30 | // Rotate polygon to have direction aligned with x-axis.
31 | // TODO(rikba): Make this independent of rotation.
32 | PolygonWithHoles rotated_polygon = rotatePolygon(polygon_in, dir);
33 |
34 | // TCD
35 | std::vector traps;
36 | CGAL::Polygon_vertical_decomposition_2 decom;
37 | decom(rotated_polygon, std::back_inserter(traps));
38 |
39 | // Rotate back all polygons.
40 | for (auto& p : traps) {
41 | CGAL::Aff_transformation_2 rotation(CGAL::ROTATION, dir, 1, 1e9);
42 | p = CGAL::transform(rotation, p);
43 | }
44 |
45 | return traps;
46 | }
47 |
48 | } // namespace polygon_coverage_planning
49 |
--------------------------------------------------------------------------------
/include/cgal_definitions.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_CGAL_DEFINITIONS_H_
21 | #define COVERAGEPLANNER_CGAL_DEFINITIONS_H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | typedef CGAL::Exact_predicates_exact_constructions_kernel K;
28 | typedef K::FT FT;
29 | typedef K::Point_2 Point_2;
30 | typedef K::Point_3 Point_3;
31 | typedef K::Vector_2 Vector_2;
32 | typedef K::Direction_2 Direction_2;
33 | typedef K::Line_2 Line_2;
34 | typedef K::Intersect_2 Intersect_2;
35 | typedef K::Plane_3 Plane_3;
36 | typedef K::Segment_2 Segment_2;
37 | typedef K::Triangle_2 Triangle_2;
38 | typedef CGAL::Polygon_2 Polygon_2;
39 | typedef Polygon_2::Vertex_const_iterator VertexConstIterator;
40 | typedef Polygon_2::Vertex_const_circulator VertexConstCirculator;
41 | typedef Polygon_2::Vertex_iterator VertexIterator;
42 | typedef Polygon_2::Vertex_circulator VertexCirculator;
43 | typedef Polygon_2::Edge_const_iterator EdgeConstIterator;
44 | typedef Polygon_2::Edge_const_circulator EdgeConstCirculator;
45 | typedef CGAL::Polygon_with_holes_2 PolygonWithHoles;
46 | typedef CGAL::Exact_predicates_inexact_constructions_kernel InexactKernel;
47 |
48 | #endif // COVERAGEPLANNER_CGAL_DEFINITIONS_H_
49 |
--------------------------------------------------------------------------------
/include/bcd.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_BCD_H_
21 | #define COVERAGEPLANNER_BCD_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | // Choset, Howie. "Coverage of known spaces: The boustrophedon cellular
26 | // decomposition." Autonomous Robots 9.3 (2000): 247-253.
27 | // https://www.cs.cmu.edu/~motionplanning/lecture/Chap6-CellDecomp_howie.pdf
28 | namespace polygon_coverage_planning {
29 |
30 | std::vector computeBCD(const PolygonWithHoles& polygon_in,
31 | const Direction_2& dir);
32 | void sortPolygon(PolygonWithHoles* pwh);
33 | std::vector getXSortedVertices(
34 | const PolygonWithHoles& p);
35 | void processEvent(const PolygonWithHoles& pwh, const VertexConstCirculator& v,
36 | std::vector* sorted_vertices,
37 | std::vector* processed_vertices,
38 | std::list* L, std::list* open_polygons,
39 | std::vector* closed_polygons);
40 | std::vector getIntersections(const std::list& L,
41 | const Line_2& l);
42 | bool outOfPWH(const PolygonWithHoles& pwh, const Point_2& p);
43 | // Removes duplicate vertices. Returns if resulting polygon is simple and has
44 | // some area.
45 | bool cleanupPolygon(Polygon_2* poly);
46 |
47 | } // namespace polygon_coverage_planning
48 |
49 | #endif // COVERAGEPLANNER_BCD_H_
50 |
--------------------------------------------------------------------------------
/include/cgal_comm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_CGAL_COMM_H_
21 | #define COVERAGEPLANNER_CGAL_COMM_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | namespace polygon_coverage_planning {
26 |
27 | // Helper to check whether a point is inside or on the boundary of the
28 | // polygon.
29 | bool pointInPolygon(const PolygonWithHoles& pwh, const Point_2& p);
30 | inline bool pointInPolygon(const Polygon_2& poly, const Point_2& p) {
31 | return pointInPolygon(PolygonWithHoles(poly), p);
32 | }
33 | bool pointsInPolygon(const PolygonWithHoles& pwh,
34 | const std::vector::iterator& begin,
35 | const std::vector::iterator& end);
36 |
37 | // Definition according to
38 | // https://doc.cgal.org/latest/Straight_skeleton_2/index.html
39 | bool isStrictlySimple(const PolygonWithHoles& pwh);
40 |
41 | // Project a point on a polygon.
42 | Point_2 projectOnPolygon2(const Polygon_2& poly, const Point_2& p,
43 | FT* squared_distance);
44 | // Project a point on the polygon boundary.
45 | Point_2 projectPointOnHull(const PolygonWithHoles& pwh, const Point_2& p);
46 |
47 | FT computeArea(const PolygonWithHoles& pwh);
48 | inline FT computeArea(const Polygon_2& poly) {
49 | return computeArea(PolygonWithHoles(poly));
50 | }
51 |
52 | // Remove collinear vertices.
53 | void simplifyPolygon(Polygon_2* polygon);
54 | void simplifyPolygon(PolygonWithHoles* pwh);
55 |
56 | PolygonWithHoles rotatePolygon(const PolygonWithHoles& polygon_in,
57 | const Direction_2& dir);
58 |
59 | // Sort boundary to be counter-clockwise and holes to be clockwise.
60 | void sortVertices(PolygonWithHoles* pwh);
61 |
62 | std::vector getHullVertices(const PolygonWithHoles& pwh);
63 | std::vector> getHoleVertices(const PolygonWithHoles& pwh);
64 |
65 | } // namespace polygon_coverage_planning
66 |
67 | #endif // COVERAGEPLANNER_CGAL_COMM_H_
68 |
--------------------------------------------------------------------------------
/include/decomposition.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_DECOMPOSITION_H_
21 | #define COVERAGEPLANNER_DECOMPOSITION_H_
22 |
23 | #include "cgal_definitions.h"
24 |
25 | namespace polygon_coverage_planning {
26 |
27 | // Get all unique polygon edge directions including opposite directions.
28 | std::vector findEdgeDirections(const PolygonWithHoles& pwh);
29 |
30 | // Get all directions that are perpendicular to the edges found with
31 | // findEdgeDirections.
32 | std::vector findPerpEdgeDirections(const PolygonWithHoles& pwh);
33 |
34 | // Find the best edge direction to sweep. The best direction is the direction
35 | // with the smallest polygon altitude. Returns the smallest altitude.
36 | double findBestSweepDir(const Polygon_2& cell, Direction_2* best_dir = nullptr);
37 |
38 | // Compute BCDs for every edge direction. Return any with the smallest possible
39 | // altitude sum.
40 | bool computeBestBCDFromPolygonWithHoles(const PolygonWithHoles& pwh,
41 | std::vector* bcd_polygons);
42 |
43 | // Compute TCDs for every edge direction. Return any with the smallest possible
44 | // altitude sum.
45 | bool computeBestTCDFromPolygonWithHoles(const PolygonWithHoles& pwh,
46 | std::vector* trap_polygons);
47 |
48 | enum DecompositionType {
49 | kBCD = 0, // Boustrophedon.
50 | kTCD // Trapezoidal.
51 | };
52 |
53 | inline bool checkDecompositionTypeValid(const int type) {
54 | return (type == DecompositionType::kBCD) || (type == DecompositionType::kTCD);
55 | }
56 |
57 | inline std::string getDecompositionTypeName(const DecompositionType& type) {
58 | switch (type) {
59 | case DecompositionType::kBCD:
60 | return "Boustrophedon Cell Decomposition";
61 | case DecompositionType::kTCD:
62 | return "Trapezoidal Cell Decomposition";
63 | default:
64 | return "Unknown!";
65 | }
66 | }
67 |
68 | } // namespace polygon_coverage_planning
69 |
70 | #endif // COVERAGEPLANNER_DECOMPOSITION_H_
71 |
--------------------------------------------------------------------------------
/include/sweep.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_SWEEP_H_
21 | #define COVERAGEPLANNER_SWEEP_H_
22 |
23 | #include "cgal_definitions.h"
24 | #include "visibility_graph.h"
25 |
26 | namespace polygon_coverage_planning {
27 |
28 | // Compute the sweep by moving from the bottom to the top of the polygon.
29 | bool computeSweep(const Polygon_2& in,
30 | const visibility_graph::VisibilityGraph& visibility_graph,
31 | const FT offset, const Direction_2& dir,
32 | bool counter_clockwise, std::vector* waypoints);
33 |
34 | // Compute sweeps in all sweepable directions, starting counter-clockwise,
35 | // clockwise, and reverse.
36 | bool computeAllSweeps(const Polygon_2& poly, const double max_sweep_offset,
37 | std::vector>* cluster_sweeps);
38 |
39 | // A segment is observable if all vertices between two sweeps are observable.
40 | void checkObservability(
41 | const Segment_2& prev_sweep, const Segment_2& sweep,
42 | const std::vector& sorted_pts, const FT max_sq_distance,
43 | std::vector::const_iterator* lowest_unobservable_point);
44 |
45 | // Find the intersections between a polygon and a line and sort them by the
46 | // distance to the perpendicular direction of the line.
47 | std::vector findIntersections(const Polygon_2& p, const Line_2& l);
48 |
49 | // Same as findIntersections but only return first and last intersection.
50 | bool findSweepSegment(const Polygon_2& p, const Line_2& l,
51 | Segment_2* sweep_segment);
52 |
53 | // Sort vertices of polygon based on signed distance to line l.
54 | std::vector sortVerticesToLine(const Polygon_2& p, const Line_2& l);
55 |
56 | // Connect to points in the polygon using the visibility graph.
57 | bool calculateShortestPath(
58 | const visibility_graph::VisibilityGraph& visibility_graph,
59 | const Point_2& start, const Point_2& goal,
60 | std::vector* shortest_path);
61 |
62 | } // namespace polygon_coverage_planning
63 |
64 | #endif // COVERAGEPLANNER_SWEEP_H_
65 |
--------------------------------------------------------------------------------
/src/weakly_monotone.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #include "weakly_monotone.h"
21 |
22 | namespace polygon_coverage_planning {
23 |
24 | bool isWeaklyMonotone(const Polygon_2& in, const Line_2& x_axis) {
25 | // Find north and south.
26 | VertexConstCirculator north = findNorth(in, x_axis);
27 | VertexConstCirculator south = findSouth(in, x_axis);
28 |
29 | // Go from south to north vertex.
30 | VertexConstCirculator c = south;
31 | VertexConstCirculator c_prev = south;
32 | for (c++; c != north; c++) {
33 | if (CGAL::has_smaller_signed_distance_to_line(x_axis, *c, *c_prev))
34 | return false;
35 | c_prev = c;
36 | }
37 |
38 | // Go opposite direction.
39 | c = south;
40 | c_prev = south;
41 | for (c--; c != north; c--) {
42 | if (CGAL::has_smaller_signed_distance_to_line(x_axis, *c, *c_prev))
43 | return false;
44 | c_prev = c;
45 | }
46 |
47 | return true;
48 | }
49 |
50 | std::vector getAllSweepableEdgeDirections(const Polygon_2& in) {
51 | // Get all directions.
52 | std::vector dirs;
53 | for (EdgeConstIterator it = in.edges_begin(); it != in.edges_end(); ++it) {
54 | // Check if this edge direction is already in the set.
55 | std::vector::iterator last =
56 | std::find_if(dirs.begin(), dirs.end(), [&it](const Direction_2& dir) {
57 | return CGAL::orientation(dir.vector(), it->to_vector()) ==
58 | CGAL::COLLINEAR;
59 | });
60 | if (last != dirs.end()) continue;
61 | // Check if the polygon is monotone perpendicular to this edge direction.
62 | if (isWeaklyMonotone(in, it->supporting_line()))
63 | dirs.push_back(it->direction());
64 | }
65 |
66 | return dirs;
67 | }
68 |
69 | VertexConstCirculator findSouth(const Polygon_2& in, const Line_2& x_axis) {
70 | VertexConstCirculator vc = in.vertices_circulator();
71 | VertexConstCirculator v = vc;
72 | do {
73 | v = CGAL::has_smaller_signed_distance_to_line(x_axis, *vc, *v) ? vc : v;
74 | } while (++vc != in.vertices_circulator());
75 | return v;
76 | }
77 |
78 | VertexConstCirculator findNorth(const Polygon_2& in, const Line_2& x_axis) {
79 | return findSouth(in, x_axis.opposite());
80 | }
81 |
82 | } // namespace polygon_coverage_planning
83 |
--------------------------------------------------------------------------------
/include/visibility_graph.h:
--------------------------------------------------------------------------------
1 | /*
2 | * polygon_coverage_planning implements algorithms for coverage planning in
3 | * general polygons with holes. Copyright (C) 2019, Rik Bähnemann, Autonomous
4 | * Systems Lab, ETH Zürich
5 | *
6 | * This program is free software: you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License as published by the Free Software
8 | * Foundation, either version 3 of the License, or (at your option) any later
9 | * version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program. If not, see .
18 | */
19 |
20 | #ifndef COVERAGEPLANNER_VISIBILITY_GRAPH_H_
21 | #define COVERAGEPLANNER_VISIBILITY_GRAPH_H_
22 |
23 | #include