Как получить полигон boost :: geometry в объект STL?
Я уверен, что это должно быть просто, потому что я не могу найти примеры нигде в документации. Тем не менее, я потратил около 4 рабочих дней, пытаясь сделать эту крошечную вещь. Я новичок в C ++ (долгое время программист на R), но эти мелкие проблемы с преобразованием данных сводят меня с ума.
Да, есть вопрос, название которого очень похоже на мое: Получение координат точек из многоугольника Boost Geometry
Но код настолько сложен (а постер постоянно менял его), что я не могу понять, как это делать, и не могу представить, что другие новички в 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, но все подойдет.
Полигоны уже находятся в формате контейнера 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;
}
И измените ваши индикаторы комментариев на // 😉
Например:
boost::geometry::model::polygon<Point> polygon;
polygon.outer().push_back( point );
Итак, polygon.outer () — это std :: vector (внешний, как сказал Баренд Герелс).
Посмотреть здесь: повысить ссылку
Вы можете использовать итераторы с моделями повышения, чтобы перебрать все точки и добавить их в любой вид контейнера, который вам нравится.
Модели многоугольников немного сложнее, потому что они имеют одно внешнее и, возможно, несколько внутренних колец.
Предполагая, что вы хотите, чтобы все точки во внешнем кольце объекта «корпус» (или любого многоугольника, включая исходный «многоугольник») просто перебирали его и добавляли их к стандартному вектору точка-точка.
Если вы хотите вектор 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 ) );
}