The Bentley-Ottoman algorithm finds all crossings in a set of line segments. For a well known and important algorithm, it seems quite weird that a C++ implementation of Bentley-Ottmann algorithm — the implementation that can handle all the degenerated cases (i.e., no special assumption on the sweeping line and the number of intersection points, and so on) — is simply not available. The only code I can found is here, but it doesn't seem to handle the generalized case.
Is Bentley-Ottmann algorithm already implemented in any well-tested library, such as Boost or LEDA? If yes, may I have the reference to it?
CGAL has something in there with the same complexity as Bentley-Ottmann, O((n + k)*log(n))
where n
is the number of segments and k
is the number of intersections (not sure which algorithm they used):
//! \file examples/Arrangement_on_surface_2/sweep_line.cpp
// Computing intersection points among curves using the sweep line.
#include <CGAL/Cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Quotient.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Sweep_line_2_algorithms.h>
#include <list>
typedef CGAL::Quotient<CGAL::MP_Float> NT;
typedef CGAL::Cartesian<NT> Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Arr_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::Curve_2 Segment_2;
int main()
{
// Construct the input segments.
Segment_2 segments[] = {Segment_2 (Point_2 (1, 5), Point_2 (8, 5)),
Segment_2 (Point_2 (1, 1), Point_2 (8, 8)),
Segment_2 (Point_2 (3, 1), Point_2 (3, 8)),
Segment_2 (Point_2 (8, 5), Point_2 (8, 8))};
// Compute all intersection points.
std::list<Point_2> pts;
CGAL::compute_intersection_points (segments, segments + 4,
std::back_inserter (pts));
// Print the result.
std::cout << "Found " << pts.size() << " intersection points: " << std::endl;
std::copy (pts.begin(), pts.end(),
std::ostream_iterator<Point_2>(std::cout, "\n"));
// Compute the non-intersecting sub-segments induced by the input segments.
std::list<Segment_2> sub_segs;
CGAL::compute_subcurves(segments, segments + 4, std::back_inserter(sub_segs));
std::cout << "Found " << sub_segs.size()
<< " interior-disjoint sub-segments." << std::endl;
CGAL_assertion (CGAL::do_curves_intersect (segments, segments + 4));
return 0;
}
http://doc.cgal.org/latest/Sweep_line_2/index.html
CGAL has an implementation of the Bently-Ottmann algorithm. You can find more about it in the 2D Sweep Line of Planar Curves section in the manual.
http://geomalgorithms.com/a09-_intersect-3.html has a discussion of the Bentley-Ottmann and Shamos-Hoey algorithms and their relationship. It ends with a C++ implementation based on binary trees. Interesting reference material if you do not want to link to CGAL or boost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With