2011-11-08 6 views
8

बूस्ट में ज्यामिति के लिए महान पुस्तकालय है। यह एसवीजी छवियों को आकर्षित करने की अनुमति देता है। मैं इसे अपनी कुछ परियोजनाओं में उपयोग करना चाहता हूं लेकिन यह मेरे लिए वास्तव में अजीब काम करता है (नीचे छवि देखें)।बूस्ट :: ज्यामिति संघ सरलीकरण - यह कैसे काम करता है?

तो हम 3 पिक्सेल अंक 2 डी अंतरिक्ष में वर्ग poligons

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 तरह एक त्रिकोण मिल d

लेकिन हम इस मिल:

enter image description here

जहां पीले Doted लाइन संघ और हरे रंग की है सरलीकरण है।

Sourcecode:

#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); 
} 

जैसे मैं pic 2 की तरह आकार पाने के लिए अर्थ करना चाहते हैं तो इसे सरल बनाने के लिए boost/geometry/extensions/io/svg/

से कम से कम बढ़ावा 1.47.0 और 3 फ़ाइलों की आवश्यकता है?

अद्यतन

निर्मित नए कोड, सही ढंग से, काफी का परीक्षण काम करता है:

#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 - 

तो अपेक्षित परिणाम pic2 से अलग है।

  • पॉलीगॉन बंद होना चाहिए, और घड़ी की दिशा निर्देशित किया जाना चाहिए।

आप समापन बिंदु खो रहे हैं और तीसरे बहुभुज को दक्षिणावर्त निर्देशित नहीं किया गया है। correct विधि पर एक नज़र डालें। इस उदाहरण पर, आपको इसे परिभाषित हर बहुभुज के लिए कॉल करना चाहिए।

  • आप जब _union का उपयोग कर इनपुट और आउटपुट के लिए एक ही तर्क का उपयोग नहीं कर सकते।

    boost::geometry::union_(one, two, outputTmp);  
        boost::geometry::union_(outputTmp, three, output); 
    
    • आपका अपेक्षित परिणाम एल्गोरिथ्म परिणाम नहीं हो सकता है:

    कि आपको अस्थायी चर का उपयोग करना चाहिए।

को सही कोड को क्रियान्वित करने के बाद, परिणाम है:

simplify result

यह आपके बहुभुज का एक मान्य simplifcation हो सकता है। Ramer–Douglas–Peucker algorithm देखें।

उन संशोधनों प्रदर्शन करने के बाद, नीचे दिए गए मुख्य जिसके परिणामस्वरूप है()

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

अधिक कोड के साथ क्यू अपडेट किया गया, अब सामान्य रूप में काम करता है लेकिन आप कैसे poligons पर भीतरी gark हरी लाइनों को हटाने के लिए पर इसके लिए एक ठीक प्रदान कर सकता है सृष्टि? – Rella

+0

मिला विचार =) मेरा समाधान पोस्ट किया गया – Rella

संबंधित मुद्दे