簡體   English   中英

boost :: geometry測量點到多邊形環的最大/最小距離的最有效方法

[英]boost::geometry Most efficient way of measuring max/min distance of a point to a polygon ring

我一直在程序中使用boost::geometry庫,主要用於處理多邊形對象。

我現在正在嘗試優化我的代碼,以便使用更大的多邊形更好地擴展。 我的一個函數檢查給定的多邊形和給定的點(通常在多邊形內),點和多邊形外環之間的最小和最大距離。

我通過循環多邊形邊來做到這一點:

polygon pol;
point myPoint;
double min = 9999999, max = 0;
for(auto it1 = boost::begin(bg::exterior_ring(pol)); it1 != boost::end(bg::exterior_ring(pol)); ++it1){
    double distance = bg::distance(*it1, myPoint);
        if(max < distance)
            max = distance;
        if(min > distance)
            min = distance;
    }

我希望有比這更快的算法,在邊的多邊形數量上是線性的。 boost::geometry庫中是否有這樣的東西?

我建議你可以使用內置策略來找到多邊形和點之間的最小距離:

住在Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/algorithms/distance.hpp>

namespace bg = boost::geometry;

using point = bg::model::d2::point_xy<double>;
using polygon = bg::model::polygon<point>;

int main() {
    polygon pol;
    boost::geometry::read_wkt(
            "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)"
            "(4.0 2.0, 4.2 1.4, 4.8 1.9, 4.4 2.2, 4.0 2.0))", pol);

    point myPoint(7, 7);
    double min = 9999999, max = 0;

    std::cout << "Minimal distance: " << bg::distance(pol, myPoint);

}

打印

Minimal distance: 4.71699

進一步提示:

您應該考慮使用comparable_distance對距離進行排名 正如您所看到的那樣,建議在所有采樣距離上進行循環...所以我認為圖書館目前沒有更好的產品。

計划更復雜的算法,其中一些可能與此問題有關:

另請注意,Boost幾何索引具有相關謂詞comparable_distance_far但尚未公開。

摘要

你現在可以在這里使用comparative_distance來改善至少一點。

已經計划了功能,看起來很有可能在郵件列表/ Boost Trac上請求它們將有助於將它們帶到那里。

為了獲得最佳性能,您應該使用帶有boost :: geometry :: index的RTree。 創建RTree有一個成本,但是然后計算點到任何(多)多邊形環的ditance會快得多。 示例代碼:

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <vector>

int main()
{
    namespace bg = boost::geometry;
    namespace bgi = boost::geometry::index;
    typedef bg::model::point<double, 2, bg::cs::cartesian> point;
    typedef bg::model::polygon<point> polygon;

    point p{ 0, 0 };
    // create some polygon and fill it with data
    polygon poly;
    double a = 0;
    double as = bg::math::two_pi<double>() / 100;
    for (int i = 0; i < 100; ++i, a += as)
    {
        double c = cos(a);
        double s = sin(a);
        poly.outer().push_back(point{10 * c, 10 * s});
        poly.inners().resize(1);
        poly.inners()[0].push_back(point{5 * c, 5 * s});
    }
    // make sure it is valid
    bg::correct(poly);

    // create rtree containing objects of type bg::model::pointing_segment
    typedef bg::segment_iterator<polygon const> segment_iterator;
    typedef std::iterator_traits<segment_iterator>::value_type segment_type;

    bgi::rtree<segment_type, bgi::rstar<4> > rtree(bg::segments_begin(poly),
                                                   bg::segments_end(poly));

    // get 1 nearest segment
    std::vector<segment_type> result;
    rtree.query(bgi::nearest(p, 1), std::back_inserter(result));

    BOOST_ASSERT(!result.empty());

    std::cout << bg::wkt(result[0]) << ", " << bg::distance(p, result[0]) << std::endl;

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM