【问题标题】:Is there a robust C++ implementation of the Bentley-Ottmann algorithm? [closed]Bentley-Ottmann 算法是否有强大的 C++ 实现? [关闭]
【发布时间】:2010-12-10 09:46:29
【问题描述】:

Bentley-Ottoman 算法查找一组线段中的所有交叉点。对于一个众所周知且重要的算法,Bentley-Ottmann 算法的 C++ 实现似乎很奇怪——该实现可以处理所有退化情况(即,对扫描线和交叉点的数量没有特殊假设,等等on) — 根本不可用。我能找到的唯一代码是here,但它似乎无法处理the generalized case

Bentley-Ottmann 算法已经在任何经过​​充分测试的库(例如 Boost 或 LEDA)中实现了吗?如果是的话,我可以参考一下吗?

【问题讨论】:

    标签: c++ computational-geometry


    【解决方案1】:

    CGAL 与 Bentley-Ottmann 具有相同的复杂性,O((n + k)*log(n)) 其中n 是段数,k 是交叉点数(不确定他们使用的是哪种算法):

    //! \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

    【讨论】:

    【解决方案2】:

    CGAL 实现了 Bently-Ottmann 算法。您可以在手册的2D Sweep Line of Planar Curves 部分找到更多相关信息。

    【讨论】:

      【解决方案3】:

      http://geomalgorithms.com/a09-_intersect-3.html 讨论了 Bentley-Ottmann 和 Shamos-Hoey 算法及其关系。它以基于二叉树的 C++ 实现结束。如果您不想链接到 CGAL 或提升,请提供有趣的参考资料。

      【讨论】:

      • C++ 实现并不完整,它只有代码显示线是否自相交。但不是查找所有交叉点的代码。
      猜你喜欢
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多