几何,交叉点

时间:2015-07-01 17:17:09

标签: c++ boost intersection boost-geometry

我有问题。我想将四边形与四边形相交。

int main(){
  typedef boost::geometry::model::point_xy<double> TBoostPoint;
  typedef boost::geometry::model::polygon<TBoostPoint> TBoostPoly;
  TBoostPoint point;
  TBoostPoly firstPoly, secondPoly;
  boost::geometry::read_wkt("POLYGON(
                (1.504477611940313, 3.761194029850755), 
                (1.504477611940305, 3.573134328358203),
                (1.316417910447765, 3.573134328358206),
                (1.316417910447769, 3.761194029850752))", firstPoly);
  boost::geometry::read_wkt("POLYGON(
                (1.504477611940313, 3.761194029850755), 
                (1.504477611940305, 3.573134328358203),
                (1.316417910447765, 3.573134328358206),
                (1.316417910447751, 3.761194029850769))", secondPoly);
 std::vector<TBoostPoly> outPoly;
 boost::geometry::intersection(firstPoly,secondPoly,outPoly);
}

outPoly - 是空的,但事实并非如此。

1 个答案:

答案 0 :(得分:3)

有两个主要问题。

输出未定义,因为输入无效。

  1. 输入WKT指定了许多无效的内环(由单点组成),而不是你预期的,一个5点的外环(不包括关闭点)。解决它:

    bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447769 3.761194029850752))", first);
    bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447751 3.761194029850769))", second); 
    
  2. Boost Geometry在整个过程中假定您永远不会对记录的前提条件产生错误。如果您阅读多边形概念页面和intersection的先决条件,您将看到完整列表¹。

    如果不这样做,则不会出现任何友好错误,只会出现无声失败,损坏或错误答案。是啊。那很糟糕。

    更糟糕的是,在Boost 1_57(IIRC)之前,BGeo甚至没有is_valid设施来测试大部分需求。好消息是,如果你升级到这个版本或以后你的生活会更简单。

  3. 在这种情况下,您会了解到多边形未正确关闭:

    <强> Live On Coliru

    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include <boost/geometry/geometries/polygon.hpp>
    #include <boost/geometry/geometries/multi_polygon.hpp>
    #include <boost/geometry/io/io.hpp>
    #include <boost/geometry/algorithms/intersection.hpp>
    #include <boost/geometry/algorithms/correct.hpp>
    #include <boost/geometry/algorithms/is_valid.hpp>
    
    namespace bg = boost::geometry;
    
    int main(){
        typedef bg::model::d2::point_xy<double> TPoint;
        typedef bg::model::polygon<TPoint>      TPoly;
        TPoly first, second;
    
        bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447769 3.761194029850752))", first);
        bg::read_wkt("POLYGON(( 1.504477611940313 3.761194029850755, 1.504477611940305 3.573134328358203, 1.316417910447765 3.573134328358206, 1.316417910447751 3.761194029850769))", second); 
    
        std::string reason;
        // polys not closed!
        if (!bg::is_valid(first, reason))  std::cout << "First polygon not valid: "  << reason << "\n";
        if (!bg::is_valid(second, reason)) std::cout << "Second polygon not valid: " << reason << "\n";
    
        bg::correct(first);
        bg::correct(second);
    
        // no more output!
        if (!bg::is_valid(first, reason))  std::cout << "First polygon not valid: "  << reason << "\n";
        if (!bg::is_valid(second, reason)) std::cout << "Second polygon not valid: " << reason << "\n";
    
        std::vector<TPoly> out;
        bg::intersection(first, second, out);
    
        for (auto& g : out)
            std::cout << "\nresult: " << bg::wkt(g) << "\n";
    }
    

    打印:

    First polygon not valid: Geometry is defined as closed but is open
    Second polygon not valid: Geometry is defined as closed but is open
    

    糟糕。地理位置没有关闭! correct(poly)在自动驾驶时为我们解决了这个问题:

    result: POLYGON((1.50448 3.57313,1.31642 3.57313,1.31642 3.76119,1.50448 3.76119,1.50448 3.57313))
    

    ¹外圈必须逆时针,内部cw,多边形必须关闭...这样的东西。