2011-11-08 62 views
8

Boost中有很好的幾何圖形庫。它也允許繪製SVG圖像。我想在我的一些項目中使用它,但它對我來說真的很奇怪(請參閱下圖)。Boost ::幾何聯合簡化 - 它是如何工作的?

因此,我們有3個像素點表示爲方形poligons 2D空間

1 1 
0 1 

enter image description here pic 1

我們希望從他們那裏得到工會和簡化它,這樣,當我們擴展它,我們」 ð得到像

1 1 1 1 1 1 
1 1 1 1 1 1 
1 1 1 1 1 1 
0 1 1 1 1 1 
0 0 1 1 1 1 
0 0 0 1 1 1 

enter image description here 三角形

,但我們得到這個:

enter image description here

其中黃色點線是工會和綠色是簡化。

源代碼:

#include <iostream> 
#include <fstream> 
#include <boost/assign.hpp> 

#include <boost/algorithm/string.hpp> 
#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/geometries.hpp> 
#include <boost/geometry/multi/geometries/multi_polygon.hpp> 
#include <boost/geometry/algorithms/envelope.hpp> 

#include <boost/geometry/extensions/io/svg/svg_mapper.hpp> 

template <typename Geometry1, typename Geometry2> 
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b) 
{ 
    typedef typename boost::geometry::point_type<Geometry1>::type point_type; 
    std::ofstream svg(filename.c_str()); 

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400); 
    mapper.add(a); 
    mapper.add(b); 

    mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2"); 
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); 
} 

int main() 
{ 

    // create points (each point == square poligon) 
    boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > one, two, three; 

    boost::geometry::read_wkt(
     "POLYGON((1 1, 1 0, 0 0, 0 1))", one); 

    boost::geometry::read_wkt(
     "POLYGON((2 2, 2 1, 1 1, 1 2))", two); 

    boost::geometry::read_wkt(
     "POLYGON((1 1, 1 2, 0 2, 0 1))", three); 

    // create a container for joined points structure 
    boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > output, simpl; 

    // join points one by one (because one day we would have many=)) 
    boost::geometry::union_(one, two, output); 
    boost::geometry::union_(output , three, output); 

    // simplify joined structure 
    boost::geometry::simplify(output, simpl, 0.5); 

    // create an svg image 
    create_svg("make_envelope.svg", simpl, output); 
} 

至少需要升壓1.47.0和3個文件從boost/geometry/extensions/io/svg/

那麼如何使它簡化像我想要的意思讓外形似pic 2

更新

創建新的代碼,工作正常,相當測試:

#include <iostream> 
#include <fstream> 
#include <boost/assign.hpp> 

//Boost 
#include <boost/algorithm/string.hpp> 
#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/geometries.hpp> 
#include <boost/geometry/multi/geometries/multi_polygon.hpp> 
#include <boost/geometry/geometries/adapted/boost_tuple.hpp> 

#include <boost/foreach.hpp> 

//and this is why we use Boost Geometry from Boost trunk 
#include <boost/geometry/extensions/io/svg/svg_mapper.hpp> 

BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) 

template <typename Geometry1, typename Geometry2> 
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b) 
{ 
    typedef typename boost::geometry::point_type<Geometry1>::type point_type; 
    std::ofstream svg(filename.c_str()); 

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400); 
    mapper.add(a); 
    mapper.add(b); 

    mapper.map(a, "fill-rule:nonzero;fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2;"); 
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); 
} 


void make_point(int x, int y, boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > & ring) 
{ 
    using namespace boost::assign; 

    boost::geometry::append( ring,  boost::geometry::model::d2::point_xy<double>(x-1, y-1)); 
    boost::geometry::append( ring,  boost::geometry::model::d2::point_xy<double>(x, y-1)); 
    boost::geometry::append( ring,  boost::geometry::model::d2::point_xy<double>(x, y)); 
    boost::geometry::append( ring,  boost::geometry::model::d2::point_xy<double>(x-1, y)); 
    boost::geometry::append( ring,  boost::geometry::model::d2::point_xy<double>(x-1, y-1)); 
    boost::geometry::correct(ring); 
} 

void create_point(int x, int y, boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > & mp) 
{ 
    boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > temp; 
    boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > ring; 
    make_point(x, y, ring); 
    boost::geometry::union_(mp, ring, temp); 
    boost::geometry::correct(temp); 
    mp=temp; 
} 

int main() 
{ 
    using namespace boost::assign; 

    typedef boost::geometry::model::polygon 
     < 
     boost::geometry::model::d2::point_xy<double> 
     > polygon; 

    typedef boost::geometry::model::multi_polygon<polygon> mp; 

    polygon ring; 

    mp pol, simpl; 
    polygon exring; 

    create_point(1,1, pol); 
    create_point(2, 1, pol); 
    create_point(3, 1, pol); 
    create_point(4,1, pol); 
    create_point(5, 1, pol); 

    create_point(1,2, pol); 
    create_point(2, 2, pol); 
    create_point(3, 2, pol); 
    create_point(4,2, pol); 
    create_point(5, 2, pol); 

    create_point(2, 3, pol); 
    create_point(3, 3, pol); 
    create_point(5, 3, pol); 

    create_point(3, 4, pol); 

    create_point(5, 3, pol); 

    create_point(5, 5, pol); 

    //boost::geometry::dissolve(ring, pol); // Baad 
    boost::geometry::simplify(pol, simpl, 0.5); // Good 

    create_svg("make_envelope.svg",pol, simpl); 
} 

而這個代碼創建這樣的圖像:

enter image description here

而對於3點返回圖像的一致好評@J. Calleja回答:

enter image description here

回答

4

我覺得有幾個問題與代碼:

  • 您所定義的多邊形:

那是:

three two 
one - 

因此,預期的結果與圖2不同。

  • 多邊形應該關​​閉,並順時針方向。

您錯過了關閉點,第三個多邊形沒有按順時針方向。看看correct方法。在這個例子中,你應該爲你定義的每個多邊形調用它。

  • 使用_union時,您不能使用輸入和輸出相同的參數。

你應該使用一個臨時變量:

boost::geometry::union_(one, two, outputTmp);  
    boost::geometry::union_(outputTmp, three, output); 
  • 您預期的結果可能不是算法的結果。

執行修正代碼後,結果是:

simplify result

這可能是你的多邊形的有效simplifcation。請參閱Ramer–Douglas–Peucker algorithm

進行這些修改後,下面是產生的main()

int main() 
{ 
    // create points (each point == square poligon)  
    boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > one, two, three; 
    boost::geometry::read_wkt(  "POLYGON((1 1, 1 0, 0 0, 0 1))", one); 
    boost::geometry::read_wkt(  "POLYGON((2 2, 2 1, 1 1, 1 2))", two); 
    boost::geometry::read_wkt(  "POLYGON((1 1, 1 2, 0 2, 0 1))", three); 
    boost::geometry::correct(one); 
    boost::geometry::correct(two); 
    boost::geometry::correct(three); 

    // create a container for joined points structure 
    boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > outputTmp, output, simpl;  
    // join points one by one (because one day we would have many=))  
    boost::geometry::union_(one, two, outputTmp);  
    boost::geometry::union_(outputTmp, three, output);  
    // simplify joined structure 
    boost::geometry::simplify(output, simpl, 0.5); 
    // create an svg image 
    create_svg("make_envelope.svg", simpl, output); 
} 
+0

有更多的代碼更新Q,現在的作品一般,但你能如何去除poligons內gark綠線爲它提供了一個修復創建? – Rella

+0

有想法=)發佈我的解決方案 – Rella

相關問題