2013-03-13 4 views
7

Как получить boost :: geometry polygon в объект STL?Преобразование boost :: geometry polygon в объект STL

Я уверен, что это должно быть просто, потому что я не могу найти примеры в документации. Тем не менее, я провел около 4 рабочих дней, пытаясь сделать эту крошечную вещь. Я новичок в C++ (долгое время R-программатор), но эти небольшие преобразования данных меня смущают.

Да, есть вопрос, название которого очень похож на мой: Getting the coordinates of points from a Boost Geometry polygon

Но код настолько сложен (и плакат держал изменил его так много раз), что я не могу сделать головы или хвосты его, и не может Я предполагаю, что другие новички C++ смогут.

Это простой пример, который должен перевести на некоторые из других типов данных boost :: geometry, так что, надеюсь, кто-то сможет следовать за ним.

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

Как получить эти координаты в контейнер STL? Я бы предпочел два std :: vector один для x и один для y, но все будет сделано.

ответ

5

Полигоны уже находятся в контейнере формата STL, у boost :: geometry :: polygon есть свое внешнее кольцо, а внутренние кольца сохраняются std :: vector по умолчанию.

Что Вы могли бы хотеть (с учетом ваших комментариев) является:

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

Это будет работать, если вы исправить вашу функцию get_coordinates к (обратите внимание на < < использование):

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

и изменить свой индикаторы комментариев к // ;-)

+1

** Я исправил несколько ошибок в своем коде, чтобы все было лучше с вашим ответом. Большое спасибо за ответ, к сожалению, я все еще не понимаю. Я долгое время пытался расшифровать [документацию по модели :: полигон] (http://www.boost.org/doc/libs/1_53_0/libs/geometry/doc/html/geometry/reference/models/ model_polygon.html), и ни разу за миллион лет не выяснилось, как добраться до очков.Позвольте мне задать несколько вопросов: – politicalEconomist

+0

1) Как вы определили, что координатные точки в объекте многоугольника называются * внешним кольцом *? Я вижу Point, PointList, RingList, точки, внутреннее кольцо, но никогда * внешнее кольцо *. 2) Как вы тогда определили, что * внешнее кольцо * хранится как std :: vector? 3) Как вы знаете, использовать 'external_ring()' для доступа к std :: vector? – politicalEconomist

+0

4) Несмотря на то, что я все это понимаю, я все еще не могу делать все, что я обычно ожидаю, я могу сделать с помощью std: vector. Например: double vectSize = boost :: geometry :: external_ring (hull) .size(); // возвращает 8 Но попытка доступа к элементам не работает: double element1 = boost :: geometry :: external_ring (hull) [0]; Ошибка: невозможно преобразовать 'boost :: tuples :: tuple ' to 'double' в инициализации – politicalEconomist

0

Например:

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

Итак, polygon.outer() является std :: vector (внешний, как сказал Barend Gehrels). См. Здесь: boost reference

0

Вы можете использовать итераторы с моделями повышения, чтобы перебирать все точки и добавлять их в любой тип контейнера, который вам нравится.

Модели Polygon немного сложнее, потому что они имеют один внешний и потенциально несколько внутренних колец.

Предполагая, что вы хотите, чтобы все точки внешнего кольца объекта «корпус» (или любой многоугольник, включая исходный «поли»), просто перебирали его и добавляли в стандартный вектор «точка-точка».

Если вы хотите, чтобы вектор x и вектор y использовали тот же метод.

::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)); 
} 
Смежные вопросы