处理2d线段的有效方法

时间:2013-03-18 12:12:53

标签: c++ data-structures kdtree r-tree

  

我有大量的2D线段。所以,我知道;电话号码,   每个线段的开始(X,Y,Z)和结束(x,Y,Z)。我想得到   给定线段的接近线段。同样适用于所有人。

     

要查找距离,我可以应用this

如果我说我的数据是;

enter image description here 所以,最后我希望将接近线作为每个线段的矢量。我听说这种类型的向量矢量可以用r-tree数据结构。我正在搜索它,但仍然无法找到相关的一个。我也看了一下opencv,有一个r-tree但它说了一些关于分类器和训练阶段...所以,我想它不适合我。

任何人都可以知道如何获取 行号,然后将其邻居行 作为ex;

  

1 = {2,4,,7,66,32,12}

     

2 = {1,4,5,6}

     

3 = {...} .. ..   这种类型的矢量使用r树。

我知道,我们可以使用kd-tree获得这种类型的向量。但它是专为点数据而设计的。因此,我认为很难在这种情况下使用kd-tree。 请帮助,谢谢。

3 个答案:

答案 0 :(得分:4)

使用任何类型的空间索引或空间分区数据结构,理论上应该可以搜索最近的分段。大多数情况下,此类空间索引的界面允许存储Box(AABB)或点,因此在这些情况下,您将被迫存储边界框的分段,然后在查询最近的框后再次检查相应的分段。但是,可以直接索引Segments。例如。在kd-tree的情况下,它将是一个包含内部节点的版本,用于定义分割平面和存储段的叶子。

Boost.Geometry R-tree支持Boost版本1.56.0及更高版本中的细分。以下是使用此空间索引实现的2d段的示例:

// Required headers
#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/index/rtree.hpp>

// Convenient namespaces
namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;
namespace bgi = boost::geometry::index;

// Convenient types
typedef bgm::point<double, 2, bg::cs::cartesian> point;
typedef bgm::segment<point> segment;
typedef std::pair<segment, size_t> value;
typedef bgi::rtree<value, bgi::rstar<16> > rtree;

// Function object needed to filter the same segment in query()
// Note that in C++11 you could pass a lambda expression instead
struct different_id
{
    different_id(size_t i) : id(i) {}
    bool operator()(value const& v) const { return v.second != id; }
    size_t id;
};

int main()
{
    // The container for pairs of segments and IDs
    std::vector<value> segments;
    // Fill the container
    for ( size_t i = 0 ; i < 10 ; ++i )
    {
        // Example segment
        segment seg(point(i, i), point(i+1, i+1));
        segments.push_back(std::make_pair(seg, i));
    }

    // Create the rtree
    rtree rt(segments.begin(), segments.end());
    // The number of closest segments
    size_t k = 3;

    // The container for results
    std::vector< std::vector<value> > closest(segments.size());

    for ( size_t i = 0 ; i < segments.size() ; ++i )
    {
        // Find k segments nearest to the i-th segment not including i-th segment
        rt.query(bgi::nearest(segments[i].first, k) && bgi::satisfies(different_id(i)),
                 std::back_inserter(closest[i]));
    }

    // Print the results
    for ( size_t i = 0 ; i < closest.size() ; ++i )
    {
        std::cout << "Segments closest to the segment " << i << " are:" << std::endl;
        for ( size_t j = 0 ; j < closest[i].size() ; ++j )
            std::cout << closest[i][j].second << ' ';
        std::cout << std::endl;
    }
}

如果您需要所有比某个阈值更接近的细分,您可以使用iterative queriesexample)。

答案 1 :(得分:3)

是的, R-trees可以做到这一点。它们设计用于具有空间扩展的任意对象,不限于点数据。实际上,一些最早的例子使用了多边形

您是否尝试过使用它们?

答案 2 :(得分:1)

构建segment Voronoi diagram,然后从邻近的单元格中获取邻近候选者。