33 #ifdef OGDF_INCLUDE_CGAL
35 # ifndef OGDF_GEOMETRIC_INEXACT_NUMBER_TYPE
36 # define OGDF_GEOMETRIC_INEXACT_NUMBER_TYPE false
48 # include <CGAL/Segment_2.h>
54 using namespace tools;
56 template<
typename kernel>
57 using LineSegment_t = CGAL::Segment_2<kernel>;
63 template<
typename kernel>
64 inline typename kernel::FT angle(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
67 return geometry::angle(l1.to_vector(), l2.to_vector());
74 template<
typename kernel>
75 inline typename kernel::FT full_angle(
const LineSegment_t<kernel>& l1,
76 const LineSegment_t<kernel>& l2) {
79 return full_angle(l1.to_vector(), l2.to_vector());
82 template<
typename kernel>
83 inline bool turn(
const LineSegment_t<kernel>& ls,
const Line_t<kernel>& l) {
84 return turn(ls.to_vector(), l.to_vector());
87 template<
typename kernel>
88 inline bool left_turn(
const LineSegment_t<kernel>& ls,
const LineSegment_t<kernel>& l) {
89 return left_turn(ls.to_vector(), l.to_vector());
92 template<
typename kernel>
93 inline bool right_turn(
const LineSegment_t<kernel>& ls,
const LineSegment_t<kernel>& l) {
94 return right_turn(ls.to_vector(), l.to_vector());
97 template<
typename kernel>
98 inline bool turn(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& p) {
99 return turn(ls.supporting_line(), p);
102 template<
typename kernel>
103 inline bool left_turn(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& p) {
104 return left_turn(ls.supporting_line(), p);
107 template<
typename kernel>
108 inline bool right_turn(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& p) {
109 return right_turn(ls.supporting_line(), p);
112 template<
typename kernel>
113 inline typename kernel::FT squared_convex_parameter_directed(
const LineSegment_t<kernel>& ls,
114 const Point_t<kernel>& p) {
116 return (ls.source() - p).squared_length() / ls.to_vector().squared_length();
119 template<
typename kernel>
120 inline typename kernel::FT squared_convex_parameter(
const LineSegment_t<kernel>& ls,
121 const Point_t<kernel>& point) {
123 return std::max(squared_convex_parameter_directed(ls, point),
124 squared_convex_parameter_directed(ls.opposite(), point));
127 template<
typename kernel>
128 inline Point_t<kernel> rel_point_at(
const LineSegment_t<kernel>& ls,
const typename kernel::FT l) {
130 return ls.source() + (ls.to_vector() * l);
133 template<
typename kernel>
134 inline typename kernel::FT value_at(
const LineSegment_t<kernel>& ls,
const typename kernel::FT x) {
135 if (ls.supporting_line().is_vertical()) {
138 return ls.supporting_line().y_at_x(x);
142 template<
typename kernel>
143 inline typename kernel::FT value_at(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& p) {
144 if (ls.supporting_line().is_vertical()) {
147 return ls.supporting_line().y_at_x(p.x());
151 template<
bool closed,
typename kernel>
152 inline bool is_on(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& point) {
154 return ls.has_on(point) && ls.target() != point;
156 return ls.has_on(point);
160 template<
typename kernel>
161 inline bool is_on(
const LineSegment_t<kernel>& ls,
const Point_t<kernel>& point) {
162 return is_on<false>(ls, point);
165 template<
typename kernel>
166 inline bool overlapping(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
167 const bool parallel = CGAL::parallel(l1.supporting_line(), l2.supporting_line());
168 const bool on_l1 = is_on<true>(l1, l2.source()) || is_on<true>(l1, l2.target());
169 const bool on_l2 = is_on<true>(l2, l1.source()) || is_on<true>(l2, l1.target());
170 return (on_l1 || on_l2) && parallel;
173 template<
typename kernel>
174 inline bool overlapping(
const LineSegment_t<kernel>& ls,
const Line_t<kernel>& line) {
175 const bool parallel = parallel(ls.supporting_line(), line);
178 const bool on_line = line.has_on(ls.source()) || line.has_on(ls.target());
179 return on_line && parallel;
182 template<
typename kernel>
183 inline bool do_intersect_wo_targets(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
184 return CGAL::do_intersect(l1, l2) && !l1.has_on(l2.target()) && !l2.has_on(l1.target());
187 template<
typename kernel>
188 inline bool do_intersect_open(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
189 return CGAL::do_intersect(l1, l2) && !l1.has_on(l2.target()) && !l2.has_on(l1.target())
190 && !l1.has_on(l2.source()) && !l2.has_on(l1.source());
193 template<
typename kernel>
194 inline bool do_intersect_wo_target(
const LineSegment_t<kernel>& l1,
const Line_t<kernel>& l) {
195 return CGAL::do_intersect(l1, l) && !l.has_on(l1.target());
198 template<
typename kernel>
199 inline bool do_intersect_wo_target(
const Line_t<kernel>& l,
const LineSegment_t<kernel>& l1) {
200 return geometry::do_intersect_wo_target(l1, l);
203 template<
typename kernel>
204 inline bool do_intersect_wo_target(
const LineSegment_t<kernel>& l1,
const Ray_t<kernel>&
r) {
205 return CGAL::do_intersect(l1,
r) && !
r.has_on(l1.target());
208 template<
typename kernel>
209 inline bool do_intersect_wo_target(
const Ray_t<kernel>&
r,
const LineSegment_t<kernel>& l1) {
210 return geometry::do_intersect_wo_target(l1,
r);
213 template<
typename kernel>
214 inline bool have_common_endpoints(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
215 return l1.source() == l2.source() || l1.source() == l2.target() || l1.target() == l1.source()
216 || l1.target() == l2.target();
219 template<
typename kernel>
220 inline Point_t<kernel> get_common_endpoint(
const LineSegment_t<kernel>& l1,
221 const LineSegment_t<kernel>& l2) {
224 if (l1.source() == l2.source() || l1.source() == l2.target()) {
231 template<
typename kernel>
232 inline Point_t<kernel> intersect(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
236 auto result = CGAL::intersection(l1, l2);
238 return Point_t<kernel>(std::numeric_limits<double>::max(),
239 std::numeric_limits<double>::max());
242 Point_t<kernel> intersection;
243 if (boost::get<LineSegment_t<kernel>>(&*result)) {
244 auto s = boost::get<LineSegment_t<kernel>>(&*result);
245 intersection = s->source();
246 }
else if (boost::get<Point_t<kernel>>(&*result)) {
247 intersection = *boost::get<Point_t<kernel>>(&*result);
255 template<
typename kernel>
256 inline Point_t<kernel> intersect(
const LineSegment_t<kernel>& l1,
const Line_t<kernel>& l2) {
259 auto result = CGAL::intersection(l1, l2);
261 return Point_t<kernel>(std::numeric_limits<unsigned int>::max(),
262 std::numeric_limits<unsigned int>::max());
265 Point_t<kernel> intersection;
266 if (boost::get<LineSegment_t<kernel>>(&*result)) {
267 auto s = boost::get<LineSegment_t<kernel>>(&*result);
268 intersection = s->source();
270 intersection = *boost::get<Point_t<kernel>>(&*result);
277 template<
typename kernel>
278 inline Point_t<kernel> intersect(
const Line_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
279 return intersect(l2, l1);
282 template<
typename kernel>
283 inline Point_t<kernel> intersect(
const LineSegment_t<kernel>& l1,
const Ray_t<kernel>&
r) {
287 auto result = CGAL::intersection(l1,
r);
289 return Point_t<kernel>(std::numeric_limits<unsigned int>::max(),
290 std::numeric_limits<unsigned int>::max());
294 Point_t<kernel> intersection;
295 if (boost::get<LineSegment_t<kernel>>(&*result)) {
296 auto s = boost::get<LineSegment_t<kernel>>(&*result);
297 intersection = s->source();
299 intersection = *boost::get<Point_t<kernel>>(&*result);
301 OGDF_ASSERT(OGDF_GEOMETRIC_INEXACT_NUMBER_TYPE || is_on<true>(l1, intersection));
302 OGDF_ASSERT(OGDF_GEOMETRIC_INEXACT_NUMBER_TYPE ||
r.has_on(intersection));
306 template<
typename kernel>
307 inline Point_t<kernel> intersect(
const Ray_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
308 return intersect(l2, l1);
311 template<
typename kernel>
312 inline typename kernel::FT order_along_seg(
const LineSegment_t<kernel>& reference
315 const LineSegment_t<kernel>& l_1,
const LineSegment_t<kernel>& l_2) {
316 auto cross = [&](
const Vector_t<kernel>& v_1,
const Vector_t<kernel>& v_2) {
317 return v_1.x() * v_2.y() - v_1.y() * v_2.x();
320 auto s = reference.target() - reference.source();
321 auto r_1 = l_1.target() - l_1.source();
322 auto r_2 = l_2.target() - l_2.source();
324 auto c_1 = cross(reference.source() - l_1.source(), s);
325 auto c_2 = cross(reference.source() - l_2.source(), s);
327 auto d_1 = cross(r_1, s);
328 auto d_2 = cross(r_2, s);
330 return c_1 * d_2 - c_2 * d_1;
333 template<
typename kernel>
334 void serialize(
const LineSegment_t<kernel>& ls, std::ostream& os) {
335 serialize(ls.source(), os);
336 serialize(ls.target(), os);
339 template<
typename kernel>
340 inline bool operator<(
const LineSegment_t<kernel>& l1,
const LineSegment_t<kernel>& l2) {
341 return l1.source() < l2.source() || (l1.source() == l2.source() && l1.target() < l2.target());
344 template<
typename Kernel,
typename T>
345 LineSegment_t<Kernel> cast(
const LineSegment_t<T>& segment) {
346 return {cast<Kernel>(segment.source()), cast<Kernel>(segment.target())};