使用增强几何缓冲区缩放多边形时的冗余顶点

Posted

技术标签:

【中文标题】使用增强几何缓冲区缩放多边形时的冗余顶点【英文标题】:Redundant vertices when scaling polygon with boost geometry buffer 【发布时间】:2018-08-22 17:20:59 【问题描述】:

我正在使用 boost geometry 来管理一些多边形,我需要将它们扩大和缩小给定的数量。我正在使用 boost::geometry::buffer 来完成这个,我想知道是否有更好的选择。我担心的是,如果我扩展一个矩形,我最终会得到一个有 12 个顶点的多边形(其中 8 个是不相关的)。下面是一些示例代码:

#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/point_xy.hpp>

using point_t = boost::geometry::model::d2::point_xy<double>;
using polygon_t = boost::geometry::model::polygon<point_t>;
using mpolygon_t = boost::geometry::model::multi_polygon<polygon_t>;

mpolygon_t expand_polygon(const polygon_t& polygon,
                          const double distance) 
    mpolygon_t scaled_polygon;
    // DistanceStrategy is symmetric; want straight lines (no curves)
    boost::geometry::strategy::buffer::distance_symmetric<double>
      distance_strategydistance;

    // SideStrategy is straight; grow equally on all sides
    boost::geometry::strategy::buffer::side_straight side_strategy;

    // JoinStrategy is miter; 1.0 as limit; Sharp (not rounded) joins
    boost::geometry::strategy::buffer::join_miter join_strategy;

    // EndStrategy is flat; flat (not rounded) ends
    boost::geometry::strategy::buffer::end_flat end_strategy;

    // PointStrategy is square; squares, not circles, if poly is just a point
    boost::geometry::strategy::buffer::point_square point_strategy;

    boost::geometry::buffer(polygon, scaled_polygon,
                            distance_strategy,
                            side_strategy,
                            join_strategy,
                            end_strategy,
                            point_strategy);

    // return scaled polygon offset by supplied distance
    return scaled_polygon;


int main() 
    using boost::geometry::get;
    polygon_t rect;
    boost::geometry::read_wkt("POLYGON((5 5,5 8,8 8,8 5, 5 5))", rect);
    mpolygon_t expanded_mpoly = expand_polygon(rect, 1.0);
    auto list_coordinates = [](const point_t& pt) 
                                std::cout.precision(std::numeric_limits<double>::max_digits10);
                                std::cout << "vertex(" << get<0>(pt)
                                          << ", " << get<1>(pt) << ")" << std::endl;
                            ;
    boost::geometry::for_each_point(expanded_mpoly, list_coordinates);

    return 0;

这是输出:

vertex(4, 5)
vertex(4, 8)
vertex(4, 9)
vertex(5, 9)
vertex(8, 9)
vertex(9, 9)
vertex(9, 8)
vertex(9, 5)
vertex(9, 4)
vertex(8, 4)
vertex(5, 4)
vertex(4, 4)
vertex(4, 5)

我需要提供策略参数吗?我应该看看其他一些提升的领地?

【问题讨论】:

【参考方案1】:

Boost 包含simplify 算法(它使用Ramer–Douglas–Peucker algorithm)。例如,在您的多边形中有 3 个点 p1,p2,p3,我们计算点 p2 和线 |p1p3| 之间的距离,如果该距离小于给定的 epsilon 值,则从多边形中删除 p2 点.因此,如果您使用具有非常小的epsilon 值的函数(以删除共线点),您可以从多边形的所有边缘中删除所有冗余点。试试这个

mpolygon_t out; // to hold new geometry
boost::geometry::simplify(expanded_mpoly,out,0.00001); // very small epsilon value
auto list_coordinates = [](const point_t& pt) 
                            std::cout.precision(std::numeric_limits<double>::max_digits10);
                            std::cout << "vertex(" << get<0>(pt)
                                      << ", " << get<1>(pt) << ")" << std::endl;
                        ;
boost::geometry::for_each_point(out, list_coordinates); // print out

你看到的输出

vertex(9, 9)
vertex(9, 4)
vertex(4, 4)
vertex(4, 9)
vertex(9, 9)

【讨论】:

这很有帮助,谢谢!在接受这个答案之前,我会再等一会儿,以防有一种方法不会产生多余的点。

以上是关于使用增强几何缓冲区缩放多边形时的冗余顶点的主要内容,如果未能解决你的问题,请参考以下文章

通过增强几何从多边形(环)裁剪多边形(环)的一部分

ZOJ 1081 Within(点是否在多边形内)| 计算几何

多边形面积(计算几何)

增强几何返回相交和相交的不一致结果

计算几何--二维几何常用算法

POJ 3855 计算几何·多边形重心