как найти самопересечение в многоугольнике с помощью boost/?

Мне нужно найти самопересечения в многоугольнике. Я знаю, что у Boost есть такая способность. но я не могу понять, как использовать turn_info для получения информации о перекрестках. как какие сегменты пересеклись и т.д. может кто поможет? спасибо


person Sergey Benkovitch    schedule 09.05.2016    source источник


Ответы (2)


Вы не можете, правильно, потому что концепции, определенные Boost Geometry, запрещают самопересечения.

Однако косвенно вы можете затем использовать функции проверки (новые с тех пор, как я думаю, 1.59), чтобы получить некоторую информацию о самопересечении:

std::string reason;
poly p;
bg::read_wkt("POLYGON((0 0, 0 4, 2 4, 2 2, 6 2, 6 6, 2 6, 2 4, 0 4, 0 8, 8 8, 8 0, 0 0))", expected);
bool ok = bg::is_valid(p, reason);
std::cout << "Expected: " << bg::dsv(p) << (ok?" valid":" invalid: '" + reason + "'") << "\n";

Отпечатки:

Ожидается: (((0, 0), (0, 4), (2, 4), (2, 2), (6, 2), (6, 6), (2, 6), (2, 4 ), (0, 4), (0, 8), (8, 8), (8, 0), (0, 0))) недопустимо: «Геометрия имеет недопустимые самопересечения. Точка самопересечения найдена в (0, 4); метод: т; операции: х/у; идентификаторы сегментов {источник, мульти, кольцо, сегмент}: {0, -1, -1, 0}/{0, -1, -1, 7}'

person sehe    schedule 09.05.2016
comment
Я вдруг понимаю, что предположил boost-geometry. Я не настолько хорошо знаком с boost-polygon, поэтому, если это контекст, мой ответ может быть неточным. - person sehe; 09.05.2016
comment
Эй, спасибо за ответ. Я точно знаю, что вы можете найти самопересечения в многоугольнике. Я видел код, который это делает. я просто не помню как. я думаю, что было использование turn_info. но я теряюсь там. если вы знаете, как использовать get turn_info, возможно, это может помочь. - person Sergey Benkovitch; 10.05.2016
comment
На самом деле я заметил сообщение в списке рассылки Boost Geometry, где... по иронии судьбы Адам Вулкевич говорит, что я видел в другом электронном письме, что вы уже поняли это.. Я действительно думаю, что вам пора разместить некоторые ссылки на это здесь, даже самоотвечающий - это действительно полезный вопрос и ответ. Как бы то ни было, вы сознательно рискуете, что люди будут крутить колеса, тратя время на вас, после того как вы уже во всем разобрались. - person sehe; 12.05.2016
comment
ИМХО Некрасиво, когда другие бегают за тобой, чтобы указать другим на эти подсказки, где ты мог бы легко позаботиться об этом сам. - person sehe; 12.05.2016

Итак, это код для получения самопересечений.

namespace bg = boost::geometry;
  using namespace std;
  typedef bg::model::d2::point_xy<double> point_2d;
  typedef bg::model::polygon<boost::geometry::model::d2::point_xy<double> > Polygon;

  Polygon poly { { { 10, 10 }, { 20, 10 }, { 20, 5 }, { 25, 5 }, { 25, 7 }, { 30, 7 }, { 30, 3 }, { 25, 3 }, { 25, 5 }, { 20, 5 }, { 20, 0 }, { 10, 0 }, { 10, 10 } }};


  typedef bg::point_type<Polygon>::type point_type;
  typedef boost::geometry::detail::overlay::turn_info<point_type, boost::geometry::segment_ratio<double> > TurnInfoType;

  bg::detail::no_rescale_policy robust_policy;
  bg::detail::self_get_turn_points::no_interrupt_policy interrupt_policy;
  std::vector<TurnInfoType> turns;

 boost::geometry::self_turns<boost::geometry::detail::overlay::assign_null_policy>(poly.outer(), robust_policy, turns, interrupt_policy);

для получения информации просто используйте что-то вроде:

turns[i].operations[0].seg_id.segment_index
person Sergey Benkovitch    schedule 15.05.2016