Пересечение геометрии Boost не выводится правильно

0

Из следующего кода я вычисляю пересечение двух многоугольников. Я надеюсь, что выход может быть NULL, если это не многоугольник. Однако выход равен (((240, 52,9999), (240, 53), (240, 53), (240, 52,9999))). Это не многоугольник. Есть ли способ проверить, действительно ли вывод является многоугольником?

#include <iostream>
#include <deque>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/algorithms/append.hpp>

#include <algorithm> // for reverse, unique
#include <iostream>
#include <string>


int main()
{
   typedef boost::geometry::model::d2::point_xy<double,    boost::geometry::cs::cartesian> point_2d;
   typedef boost::geometry::model::polygon<point_2d> polygon_2d;

    polygon_2d green;
    boost::geometry::append(green, point_2d(286.188, 90.9575));
    boost::geometry::append(green, point_2d(274.902, 56.2215));
    boost::geometry::append(green, point_2d(274.238, 55.7393));
    boost::geometry::append(green, point_2d(246.908, 51.9765));
    boost::geometry::append(green, point_2d(194.477, 59.7441));
    boost::geometry::append(green, point_2d(159.213, 101.141));
    boost::geometry::append(green, point_2d(203.576, 149.537));
    boost::geometry::append(green, point_2d(286.188, 90.9575));

    polygon_2d blue;
    boost::geometry::append(blue, point_2d(240, 53));
    boost::geometry::append(blue, point_2d(240, -53));
    boost::geometry::append(blue, point_2d(-60, -53));
    boost::geometry::append(blue, point_2d(-60, 53));
    boost::geometry::append(blue, point_2d(240, 53));

    boost::geometry::correct(green);
    boost::geometry::correct(blue);

    std::vector<polygon_2d> output;
    boost::geometry::intersection(green, blue, output);

    std::cout << "green && blue:" << std::endl;
    if(output.size())
    {
       std::cout<<boost::geometry::dsv(output[0])<<std::endl;
       std::cout<<boost::geometry::area(output[0])<<std::endl;
    }

    return 0;
}
Теги:
boost
intersection
boost-geometry

1 ответ

1

Вы можете вырезать неверные геометрии:

output.erase(
        std::remove_copy_if(output.begin(), output.end(), output.begin(), [](polygon_2d const&g) { return boost::geometry::is_valid(g); }),
        output.end());

Теперь результат будет пустым, как ожидалось.

Посмотреть Live On Coliru


Мне интересно, как в первую очередь возникнут "недействительные" геометрии. Поскольку вы, вероятно, знали, что ваши полигоны очень хорошо выбраны:

Изображение 174551 Немного увеличьте изображение: Изображение 174551

Теперь вы, вероятно, смотрите на некоторые вопросы точности с плавающей запятой, так как тот же эксперимент с long long точками или boost multiprecision, например:

typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<1024*128>> oopmh; // that a lotta oomph
typedef boost::geometry::model::d2::point_xy<oopmh, boost::geometry::cs::cartesian> point_2d;

Вы увидите, что мы получаем

green && blue:
(((2.4e+06, 530000), (-600000, 530000), (-600000, -530000), (2.4e+06, -530000), (2.4e+06, 530000)))
nan

Так что это очень похоже на то, что мы просто получаем особую точку области. Если вы этого не хотите, то, возможно, вам нужно просто определить значение типа "эпсилон", пороговое значение, при котором вы перестаете рассматривать перекрытие с перекрытием.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню