我學習了如何使用帶有自定義多邊形的 boost::polygon 庫。我舉了一個使用自定義多邊形的例子,并試圖得到這些的交集。我沒有得到任何交集,也不明白為什么。另外,你可以看到這個建構式
CPoint(boost::polygon::point_data<int> pd)
沒有它我就無法編譯我的程式。有人可以解釋一下,為什么我需要它?我做錯了什么?
/*
Copyright 2008 Intel Corporation
Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
*/
#include <boost/polygon/polygon.hpp>
#include <cassert>
#include <list>
namespace gtl = boost::polygon;
using namespace boost::polygon::operators;
template <typename Polygon>
void test_polygon()
{
typedef typename gtl::polygon_traits<Polygon>::point_type Point;
Point pts[] = {gtl::construct<Point>(6, 0),
gtl::construct<Point>(0, 6),
gtl::construct<Point>(-6, 0),
gtl::construct<Point>(0, -6),
};
Polygon poly, poly2;
gtl::set_points(poly, pts, pts 5);
Point pts2[] = {gtl::construct<Point>(4, 0),
gtl::construct<Point>(4, 4),
gtl::construct<Point>(0, 4),
gtl::construct<Point>(0, 0),
};
gtl::set_points(poly2, pts2, pts2 5);
std::vector<Polygon> res;
//boost::polygon::polygon_set_data<int> res;
//res = poly;
//assign(res, poly);
res.push_back(poly);
res &= poly2;
std::cout << "size = " << res.size() << std::endl;
assert(!res.empty());
//for(auto it = res[0].begin(); it != res[0].end(); it)
// std::cout << "Point(" << it->x << ", " << it->y << ")" << std::endl;
assert(gtl::area(poly) == 100.0f);
}
struct CPoint {
CPoint()=default;
CPoint(boost::polygon::point_data<int> pd) /*---> WHY? What for ? I implemented constructor with traits*/
{
x = pd.x();
y = pd.y();
}
int x;
int y;
};
namespace boost { namespace polygon {
template <>
struct geometry_concept<CPoint> { typedef point_concept type; };
template <>
struct point_traits<CPoint> {
typedef int coordinate_type;
static inline coordinate_type get(const CPoint& point,
orientation_2d orient) {
if(orient == HORIZONTAL)
return point.x;
return point.y;
}
};
template <>
struct point_mutable_traits<CPoint> {
typedef int coordinate_type;
static inline void set(CPoint& point, orientation_2d orient, int value) {
if(orient == HORIZONTAL)
point.x = value;
else
point.y = value;
}
static inline CPoint construct(int x_value, int y_value) {
CPoint retval;
retval.x = x_value;
retval.y = y_value;
return retval;
}
};
}
}
typedef std::list<CPoint> CPolygon;
namespace boost {
namespace polygon {
template <>
struct geometry_concept<CPolygon>{ typedef polygon_concept type; };
template <>
struct polygon_traits<CPolygon> {
typedef int coordinate_type;
typedef CPolygon::const_iterator iterator_type;
typedef CPoint point_type;
static inline iterator_type begin_points(const CPolygon& t) {
return t.begin();
}
static inline iterator_type end_points(const CPolygon& t) {
return t.end();
}
static inline std::size_t size(const CPolygon& t) {
return t.size();
}
static inline winding_direction winding(const CPolygon& t) {
return clockwise_winding;
}
};
template <>
struct polygon_mutable_traits<CPolygon> {
template <typename iT>
static inline CPolygon& set_points(CPolygon& t,
iT input_begin, iT input_end) {
t.clear();
t.insert(t.end(), input_begin, input_end);
return t;
}
};
}
}
int main() {
test_polygon<CPolygon>();
return 0;
}
我在交叉點的結果向量中得到 size = 0。
uj5u.com熱心網友回復:
gtl::set_points(poly, pts, pts 5);
這是越界的,因為陣列只有 4 個元素。通過現代化避免整個錯誤類別:
std::array const pts1{
gtl::construct<Point>(6, 0),
gtl::construct<Point>(0, 6),
gtl::construct<Point>(-6, 0),
gtl::construct<Point>(0, -6),
};
std::array const pts2{
gtl::construct<Point>(4, 0),
gtl::construct<Point>(4, 4),
gtl::construct<Point>(0, 4),
gtl::construct<Point>(0, 0),
};
進而
Polygon poly1;
gtl::set_points(poly1, pts1.begin(), pts1.end());
Polygon poly2;
gtl::set_points(poly2, pts2.begin(), pts2.end());
接下來你有:
static inline winding_direction winding(const CPolygon& t)
{
return clockwise_winding;
}
但是你的樣本資料不符合那個繞組。修復您的輸入資料:
std::array const pts1{
gtl::construct<Point>(0, -6),
gtl::construct<Point>(-6, 0),
gtl::construct<Point>(0, 6),
gtl::construct<Point>(6, 0),
};
std::array const pts2{
gtl::construct<Point>(0, 0),
gtl::construct<Point>(0, 4),
gtl::construct<Point>(4, 4),
gtl::construct<Point>(4, 0),
};
最后,Boost Polygon 中算子的結果是一個多邊形集視圖。您可以讓圖書館分配:
std::vector<Polygon> res;
gtl::assign(res, poly1 & poly2);
或者
std::vector<Polygon> res{poly1};
res &= poly2;
哪個實際上等效,但第二個可能更有效?
fmt::print("poly1 {}, area {}\n", poly1, gtl::area(poly1));
fmt::print("poly2 {}, area {}\n", poly2, gtl::area(poly2));
fmt::print("res {}, area {}\n", res, gtl::area(res));
印刷

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/362851.html
上一篇:計數符號變化
下一篇:用C 實作矩陣運算
