[英]Map-geometry intersection of two 3d linestrings using Boost
我正在嘗試使用 Boost 確定兩個 3d 線串之間的交點,但在某些情況下,我沒有得到預期的結果。
根據我的理解 [1],Boost 應該使用Map 幾何來計算交點 - 即不考慮 Z 坐標。 這是我追求的功能。
但是,我的測試顯示如果一個線串總是在另一個線串之上(下面代碼清單中的案例 1),那么我沒有得到任何交叉點。
但是,如果第二條線穿過包含第一條線的平面 - 案例 2 - 則找到一個交點 - 即使兩條線在 3d 空間中不相交。
我的理解錯了嗎? 或者,有沒有辦法讓案例 1 工作?
我的解決方法是確保第一個線串始終穿過第二個線串的平面……但這似乎很笨拙。
謝謝
#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
namespace bg = boost::geometry;
int main()
{
typedef bg::model::point<double, 3, bg::cs::cartesian> point_t;
typedef bg::model::linestring<point_t> linestring_t;
linestring_t ls1{{0, 0, 1}, {1, 1, 1}};
linestring_t ls2{{0, 1, 0}, {1, 0, 0}};
linestring_t ls3{{0, 1, 0}, {1, 0, 1}};
std::vector<point_t> intersections;
bg::intersection(ls1, ls2, intersections);
std::cout << "Case 1: Intersection between l1 and l2? " << (intersections.size() > 0 ? "Yes" : "No") << std::endl;
bg::intersection(ls1, ls3, intersections);
std::cout << "Case 2: Intersection between l1 and l3? " << (intersections.size() > 0 ? "Yes" : "No") << std::endl;
return 0;
}
output:
Case 1: Intersection between l1 and l2? No
Case 2: Intersection between l1 and l3? Yes
參考:
[1] “如何通過 Boost C++ 庫與 3D 多邊形相交?”, https://stackoverflow.com/a/49012544/
鏈接的答案僅表明
area
確實支持實現尺寸>2¹ 我今天找不到關於intersection
的任何不同之處。 令我驚訝的是,文檔沒有明確警告未指明的行為。
但是,似乎獲得地圖地理行為的唯一方法是手動映射:
#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))
¹當時,甚至沒有檢查是否改變了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.