В связанном ответе просто говорится, что
- Boost Geometry
area
действительно поддерживает размеры реализации> 2¹ - Стандарт OGM позволяет соответствующим реализациям работать с геометрией карты, хотя они могут реализовать полную трехмерную геометрию, если она соответствует другому стандарту.
Сегодня я не могу найти ничего другого в отношении intersection
. Для меня довольно удивительно, что в документации нет четких предупреждений о неуказанном поведении.
Однако, похоже, единственный способ получить поведение map-geo - вручную сопоставить:
Live On Coliru
#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/geometries/multi_point.hpp>
#include <boost/geometry/algorithms/for_each.hpp>
namespace bg = boost::geometry;
static inline constexpr auto io = [](auto& g) { return bg::dsv(g); }; // switch to bg::wkt easily
using point_t = bg::model::point<double, 3, bg::cs::cartesian>;
using points_t = bg::model::multi_point<point_t>;
using linestring_t = bg::model::linestring<point_t>;
struct ZeroZ {
inline void operator()(point_t& p) const { p.set<2>(0); }
template <typename G> void operator()(G& g) const { bg::for_each_point(g, *this); }
} static inline constexpr zeroz{};
int main() {
std::cout << std::fixed << std::setprecision(2);
linestring_t const lss[] = {
{{0, 0, 1}, {1, 1, 1}},
{{0, 1, 0}, {1, 0, 0}},
{{0, 1, 0}, {1, 0, 1}},
};
for (auto a : lss) for (auto b : lss) {
points_t c, d;
bg::intersection(a, b, c);
std::cout << "Normal: " << io(a) << " with " << io(b) << " ->" << io(c) << "\n";
zeroz(a);
zeroz(b);
bg::intersection(a, b, d);
if (!bg::equals(c, d))
std::cout << " -- but: " << io(a) << " with " << io(b) << " ->" << io(d) << "\n";
}
}
Печать
Normal: ((0.00, 0.00, 1.00), (1.00, 1.00, 1.00)) with ((0.00, 0.00, 1.00), (1.00, 1.00, 1.00)) ->((0.00, 0.00, 1.00), (1.00, 1.00, 1.00))
-- but: ((0.00, 0.00, 0.00), (1.00, 1.00, 0.00)) with ((0.00, 0.00, 0.00), (1.00, 1.00, 0.00)) ->((0.00, 0.00, 0.00), (1.00, 1.00, 0.00))
Normal: ((0.00, 0.00, 0.00), (1.00, 1.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) ->((0.50, 0.50, 0.00))
Normal: ((0.00, 0.00, 0.00), (1.00, 1.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 1.00)) ->((0.50, 0.50, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 0.00, 1.00), (1.00, 1.00, 1.00)) ->()
-- but: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 0.00, 0.00), (1.00, 1.00, 0.00)) ->((0.50, 0.50, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) ->((0.00, 1.00, 0.00), (1.00, 0.00, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 1.00)) ->((0.00, 1.00, 0.00), (1.00, 0.00, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 1.00)) with ((0.00, 0.00, 1.00), (1.00, 1.00, 1.00)) ->((0.50, 0.50, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) ->((0.00, 1.00, 0.00), (1.00, 0.00, 0.00))
Normal: ((0.00, 1.00, 0.00), (1.00, 0.00, 0.00)) with ((0.00, 1.00, 0.00), (1.00, 0.00, 1.00)) ->((0.00, 1.00, 0.00), (1.00, 0.00, 0.00))
¹ в то время, даже не проверено, изменилось ли это