学习使用库来诊断您的问题:
std::string reason;
bool ok = bg::is_valid(P, reason);
std::cout << "Polygon " << (ok?"valid":"invalid") << " (" << reason << ")\n";
打印:Live On Coliru
Polygon invalid (Geometry has too few points)
您还可以在 WKT/DSV(甚至 SVG)中打印几何图形:Live On Coliru
POLYGON((0 0)) invalid (Geometry has too few points)
Area:0
这让问题更加明显。
您不想添加一个点,而是添加一个环。实现这一点的最简单方法是明确地将其设为环:
ring_type points {
{ 0, 0 },
{ 100, 0 },
{ 100, 100 },
{ 0, 100 },
{ 0, 0 },
};
bg::append(P, points);
仍然不行,但更好:Live On Coliru
POLYGON((0 0,100 0,100 100,0 100,0 0)) invalid (Geometry has wrong orientation)
Area:-10000
如您所见,我们的方向错误(应该是顺时针方向):
ring_type points {
{ 0, 0 },
{ 0, 100 },
{ 100, 100 },
{ 100, 0 },
{ 0, 0 },
};
打印:Live On Coliru
POLYGON((0 0,0 100,100 100,100 0,0 0)) valid (Geometry is valid)
Area:10000
注意您可以使用bg::correct 来纠正直截了当的有效性问题,例如。
样式和类型
其实环型就是多边形类型的外环型:
static_assert(std::is_same<ring_type, polygon_type::ring_type>{}, "synonyms");
static_assert(bg::point_order<ring_type>::value == bg::order_selector::clockwise, "orientation");
因此,可以直接从外环初始化器构造:
polygon_type P { {
{ 0, 0 },
{ 0, 100 },
{ 100, 100 },
{ 100, 0 },
{ 0, 0 },
} };
将整个程序压缩为一行:Live On Coliru
int main() {
typedef bgm::polygon<bgm::d2::point_xy<double> > polygon_type;
std::cout << "Area:" << bg::area(polygon_type { { {0, 0}, {0, 100}, {100, 100}, {100, 0}, {0, 0} } }) << std::endl;
}
或者您可以,确实从 WKT/DSV 中读取它:Live On Coliru
int main() {
bgm::polygon<bgm::d2::point_xy<double> > P;
bg::read_wkt("POLYGON((0 0,0 100,100 100,100 0,0 0))", P);
std::cout << "Area:" << bg::area(P) << std::endl;
}
仍在打印
Area:10000