【问题标题】:Boost-geometry : Polygon definitionBoost-geometry:多边形定义
【发布时间】:2017-12-29 08:57:54
【问题描述】:

你能告诉我为什么这个多边形定义不起作用吗?

namespace bg = boost::geometry;

int main()
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point_type;
typedef bg::model::polygon<point_type> polygon_type;

polygon_type P;

int xi[] = {0,100,100,0,0};
int yi[] = {0,0,100,100,0};

bg::append(P, bg::make<point_type>(*xi, *yi));

double area = bg::area(P);
std::cout << "Area:" << area << std::endl;

Return 0; }

这显示区域:0

谢谢

【问题讨论】:

    标签: c++ polygon boost-geometry


    【解决方案1】:

    学习使用库来诊断您的问题:

    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
    

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多