Из следующего кода я вычисляю пересечение двух многоугольников. Я надеюсь, что выход может быть 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;
}
Вы можете вырезать неверные геометрии:
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
Мне интересно, как в первую очередь возникнут "недействительные" геометрии. Поскольку вы, вероятно, знали, что ваши полигоны очень хорошо выбраны:
Немного увеличьте изображение:
Теперь вы, вероятно, смотрите на некоторые вопросы точности с плавающей запятой, так как тот же эксперимент с 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
Так что это очень похоже на то, что мы просто получаем особую точку области. Если вы этого не хотите, то, возможно, вам нужно просто определить значение типа "эпсилон", пороговое значение, при котором вы перестаете рассматривать перекрытие с перекрытием.