2013-03-13 7 views
7

Wie bekomme ich ein boost :: geometry polygon in ein STL-Objekt?Transformieren eines Boost :: Geometrie-Polygons in ein STL-Objekt

Ich bin sicher, dass dies einfach sein muss, weil ich nirgendwo in der Dokumentation Beispiele finden kann. Dennoch habe ich etwa 4 volle Arbeitstage damit verbracht, dieses winzige Ding zu machen. Ich bin neu in C++ (lange Zeit R Programmierer), aber diese kleinen Daten Umwandlung Dinge fahren mich verrückt.

Ja, es ist eine Frage, deren Titel ist ähnlich wie meins: Getting the coordinates of points from a Boost Geometry polygon

Aber der Code ist so komplex (und das Plakat gehalten änderte es so oft), dass ich nicht Kopf oder Zahl davon machen kann, noch kann Ich kann mir vorstellen, dass andere C++ -Neulinge dazu in der Lage sein werden.

Dies ist ein einfaches Beispiel, das in einige der anderen Boost :: Geometrie-Datentypen übersetzt werden sollte, so dass hoffentlich jeder es folgen kann.

#include <iostream> 

#include <boost/geometry.hpp> 
#include <boost/geometry/geometries/polygon.hpp> 
#include <boost/geometry/geometries/adapted/boost_tuple.hpp> 

BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) 

//One thing I tried is a function to use with `for_each_point()` so I set that up first. 

    template <typename Point> 
    void get_coordinates(Point const& p) 
    { 
    using boost::geometry::get; 
    std::cout << get<0>(p) get<1>(p) << std::endl; 
    } 

    int main() 
    { 
    typedef boost::tuple<double, double> point; 
    typedef boost::geometry::model::polygon<point> polygon; 

    polygon poly; 
    boost::geometry::read_wkt("polygon((2.0 1.3, 2.4 1.7, 2.8 1.8, 3.4 1.2, 3.7 1.6, 3.4 2.0, 4.1 3.0, 5.3 2.6, 5.4 1.2, 4.9 0.8, 2.9 0.7, 2.0 1.3))", poly); 

    polygon hull; 
    boost::geometry::convex_hull(poly, hull); 

// Now I know I can `dsv()` and print to the screen like this: 

    using boost::geometry::dsv; 
    std::cout 
    << "hull: " << dsv(hull) << std::endl; 

    // And/Or I can use my function with for_each_point() 



    boost::geometry::for_each_point(hull, get_coordinates<point>); 

return 0; 
} 

Wie bekomme ich diese Koordinaten in einen STL-Container? Ich würde zwei std :: vector eins für x und eins für y bevorzugen, aber alles wird tun.

Antwort

5

Polygone sind bereits in einem STL-Container-Format, der äußere Ring des Boost :: Geometrie :: Polygons ist standardmäßig und der innere Ring ist standardmäßig ein std :: Vektor.

Was möchten Sie vielleicht (Ihre Kommentare unter Berücksichtigung) ist:

polygon hull; 
    boost::geometry::convex_hull(poly, hull); 
    boost::geometry::for_each_point(boost::geometry::exterior_ring(hull), get_coordinates<point>); 

Das funktioniert, wenn Sie Ihre get_coordinates Funktion (man beachte die < < usage) korrigieren:

template <typename Point> 
    void get_coordinates(Point const& p) 
    { 
     using boost::geometry::get; 
     std::cout << get<0>(p) << ", " << get<1>(p) << std::endl; 
    } 

und ändern Sie Ihre Kommentar-Indikatoren zu // ;-)

+1

** Ich habe ein paar Fehler in meinem Code behoben, damit die Dinge besser zu Ihrer Antwort passen. Vielen Dank für die Antwort, leider bekomme ich es immer noch nicht. Ich habe lange Zeit versucht, die [Dokumentation für Modell :: Polygon] zu entziffern (http://www.boost.org/doc/libs/1_53_0/libs/geometry/doc/html/geometry/reference/models/ model_polygon.html) und hätte nie in einer Million Jahren herausgefunden, wie man zu den Punkten kommt.Lassen Sie mich ein paar Fragen stellen: – politicalEconomist

+0

1) Wie haben Sie festgestellt, dass die Koordinatenpunkte im Polygonobjekt als * Außenring * bezeichnet werden? Ich sehe Point, PointList, RingList, Punkte, innerer Ring, aber niemals * äußeren Ring *. 2) Wie haben Sie dann festgestellt, dass der * äußere Ring * als std :: vector gespeichert ist? 3) Woher wussten Sie, 'exterior_ring()' zu verwenden, um auf den std :: vector zuzugreifen? – politicalEconomist

+0

4) Obwohl ich all das jetzt verstehe, kann ich immer noch nicht all die Dinge tun, die ich normalerweise mit einem std: vector tun kann. Zum Beispiel: double vectSize = boost :: geometry :: exterior_ring (Rumpf) .size(); // returns 8 Der Zugriff auf die Elemente funktioniert jedoch nicht: double element1 = boost :: Geometrie :: exterior_ring (Rumpf) [0]; Fehler: kann Boost :: Tupel :: Tupel nicht konvertieren in Initialisierung – politicalEconomist

0

Zum Beispiel:

boost::geometry::model::polygon<Point> polygon; 
polygon.outer().push_back(point); 

Also, polygon.outer() ist std :: vector (externe, wie Barend Gehrels sagte). Siehe hier: boost reference

0

Sie können Iteratoren mit den Boost-Modellen verwenden, um über alle Punkte zu iterieren und sie zu einem beliebigen Container hinzuzufügen.

Polygon-Modelle sind etwas komplizierter, weil sie einen einzelnen äußeren und möglicherweise mehrere innere Ringe haben.

Angenommen, Sie möchten alle Punkte im äußeren Ring des "hull" -Objekts (oder irgendein Polygon, einschließlich des ursprünglichen "poly"), iterieren Sie einfach darüber und fügen Sie sie einem Standardvektor Punkt für Punkt hinzu.

Wenn Sie einen Vektor von x und einen Vektor von y möchten, verwenden Sie die gleiche Methode.

::std::vector<point> hullPoints; 
::std::vector<double> hullXPoints; 
::std::vector<double> hullYPoints; 

// the auto keyword makes declaring iterators easy 
for (auto hullIterator = hull.outer().begin; 
     hullIterator != hull.outer().end(); 
     ++hullIterator) 
{ 
    // for a vector of point types, just add the points one by one 
    hullPoints.push_back(*hullIterator); 

    // for vectors of x and y, extract the x/y from the point 
    hullXPoints.push_back(get<0>(*hullIterator)); 
    hullYPoints.push_back(get<1>(*hullIterator)); 
}