33#ifdef OGDF_INCLUDE_CGAL
48# include <CGAL/Polygon_2.h>
57template<
typename kernel>
58class Polygon_t :
public CGAL::Polygon_2<kernel> {
60 using poly = CGAL::Polygon_2<kernel>;
73 inline typename poly::Edge_const_iterator begin()
const {
return poly::edges_begin(); }
75 inline typename poly::Edge_const_iterator end()
const {
return poly::edges_end(); };
78 if (poly::is_empty() || (poly::container().back() != x)) {
89template<
typename kernel,
typename Graph>
91 const graph::Path& path) {
93 for (
auto& v : path.nodes()) {
94 polygon.push_back(
drawing.get_point(v));
99template<
typename kernel,
typename Graph>
101 const graph::Path& path) {
104 for (
unsigned int i = 0; i < path.edges().
size(); ++i) {
105 auto e = path.edges()[i];
107 if (!path.is_reversed(i)) {
109 polygon.push_back(p);
112 auto& p =
drawing.get_polyline(e);
113 for (
auto itr = p.rbegin();
itr != p.rend(); ++
itr) {
114 polygon.push_back(*
itr);
121template<
typename kernel>
124 for (
unsigned int i = 0; i < 4; ++i) {
125 p.push_back(
rect[i]);
130template<
typename kernel>
136template<
typename kernel>
139 std::vector<Point_t<kernel>>
is;
142 if (geometry::do_intersect_wo_target(line, s)) {
143 is.push_back(geometry::intersect(line, s));
150template<
typename kernel,
typename Graph>
152 graph::GeometricDrawing<kernel, Graph>&
drawing) {
153 std::vector<typename Graph::Node>
node_map;
154 for (
unsigned int i = 0; i < polygon.size(); ++i) {
155 typename Graph::Node u =
drawing.get_graph().add_node();
156 drawing.set_point(u, polygon[i]);
160 for (
unsigned int i = 0; i < polygon.size(); ++i) {
167template<
typename kernel>
169 return (i + 1) % p.size();
172template<
typename kernel>
174 return std::min((
size_t)i - 1, p.size() - 1);
177template<
typename kernel>
179 return std::move(
Polygon_t<kernel>(polygon.container().rbegin(), polygon.container().rend()));
182template<
typename kernel>
183inline bool contains(
const Polygon_t<kernel>& polygon,
const geometry::Point_t<kernel>& p) {
185 if (polygon.size() == 0) {
188 if (polygon.size() == 1) {
189 return polygon[0] == p;
191 if (CGAL::is_zero(CGAL::abs(polygon.area()))) {
193 for (
const auto& s : polygon) {
201 unsigned int segment = -1;
202 geometry::LineSegment_t<kernel>
l;
205 l = {p, polygon[segment] + polygon.edge(segment).to_vector() * 0.5};
210 geometry::Ray_t<kernel>
r(p,
l.to_vector());
214 for (
unsigned int i = 0; i < polygon.size(); ++i) {
215 auto s = polygon.edge(i);
217 if (geometry::do_intersect_wo_target(s,
r)) {
218 auto is = geometry::intersect(s,
r);
219 if (
is == s.source()) {
220 auto prev_seg = polygon.edge(prev(polygon, i));
221 if (!geometry::right_turn(
prev_seg, s)) {
234template<
typename Kernel>
236 typename Kernel::FT
min_dist = CGAL::squared_distance(*polygon.begin(), point);
237 for (
const auto& e : polygon) {
238 typename Kernel::FT
sq = CGAL::squared_distance(e, point);
243 if (
min_dist > 1e-12 && !contains(polygon, point)) {
251template<
typename Kernel>
257 p = p * (1.0 / polygon.size());
261template<
typename kernel>
271template<
typename kernel>
275 for (
auto s : polygon) {
276 if (geometry::do_intersect_wo_target(s,
ray)) {
277 return geometry::intersect(s,
ray);
283template<
typename kernel>
285 return polygon.area() < 0;
288template<
typename kernel>
290 std::vector<unsigned int>
segment_ids(polygon.size(), 0);
291 for (
unsigned int i = 0; i < polygon.size(); ++i) {
295 return (polygon.edge(i).min() < polygon.edge(j).min())
296 || (polygon.edge(i).min() == polygon.edge(j).min()
297 && polygon.edge(i).max() < polygon.edge(j).max());
300 std::vector<unsigned int>
is_duplicate(polygon.size(), -1);
301 for (
unsigned int i = 0; i + 1 < polygon.size(); ++i) {
304 if (polygon.edge(a).min() == polygon.edge(b).min()
305 && polygon.edge(a).max() == polygon.edge(b).max()) {
313template<
typename kernel>
315 std::stringstream
os;
317 for (
unsigned int i = 0; i < polygon.size(); ++i) {
319 if (i + 1 < polygon.size()) {
327template<
typename kernel>
Reverse< T > reverse(T &container)
Provides iterators for container to make it easily iterable in reverse.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
const T & move(const T &v)
The namespace for all OGDF objects.
std::ostream & operator<<(std::ostream &os, const ogdf::Array< E, INDEX > &a)
Prints array a to output stream os.