efficient way to handle 2d line segments
Asked Answered
F

3

9

I am having huge set of 2D line segments. So, I know; Line number, Begin (X,Y,Z) and End (x,Y,Z) of each line segment. I want to get proximity line segments for a given line segment. Likewise for all.

To find the proximity I can apply this

If I say my data it is as;

enter image description here So, at the end I want to get proximity lines as a vector for each line segment. I heard this type of vector of vector can be taken with r-tree data structures. I was searching it but still could not find the relevant one for me. Also I looked in opencv, there is a r-tree but it says something about classifier, and training phase... so, i guess it doesn't fit me.

Can anyone know how to get line no , then its neighbor lines for ex;

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

2 = {1,4,5,6}

3 = {...} .. .. this type of vector of vector using r-tree.

I know, we can get this type of vectors using kd-tree. But it is designed for the point data. So, it is hard to use kd-tree for this case i think. any help please, thank you.

Flareup answered 18/3, 2013 at 12:12 Comment(0)
S
4

Theoretically searching for the nearest Segments should be possible using any kind of spatial index or space partitioning data structure. Most often the interface of such spatial index allows to store Boxes (AABBs) or Points so in these cases you'd be forced to store bounding Boxes of Segments and then after querying for the closest Boxes check again the corresponding Segments. However it's possible to index Segments directly. E.g. in case of kd-tree it would be a version containing internal nodes defining splitting planes and leafs storing segments.

Boost.Geometry R-tree supports Segments in Boost version 1.56.0 and above. Below is the example for 2d segments using this spatial index implementation:

// 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;
    }
}

In case you needed ALL of the Segments that are closer than some threshold you could use iterative queries (example).

Saltant answered 1/8, 2014 at 15:43 Comment(0)
K
3

Yes, R-trees can do this. They are designed for arbitrary objects with spatial extend, not limited to point data. Actually some of the earliest examples used polygons.

Have you tried using them?

Kelleher answered 18/3, 2013 at 17:47 Comment(6)
I tried to use it. But I cannot figure it out with opencv. As the things that I found says training phase and classifier. me, I do not have a training phase.. If you guide me on this, I am really appreciated. thank you,Flareup
R-trees have nothing to do with classification. They should have a "find nearest neighbors" function. But I have never used opencv.Kelleher
then, please let me know other libraries which I can use to get this type of nearest neighbors. thanksFlareup
Actually, I was trying to use below two links.. But, for me, I could not find a way to use either for my case. docs.opencv.org/modules/ml/doc/random_trees.html and public.cranfield.ac.uk/c5354/teaching/ml/examples/c++/… Any help is appreciated. thank you.Flareup
Random forest usually refers to decision trees. These are not R-trees. It's something entirely different, they have little in common except using a tree-like data structure somewhere.Kelleher
Try libspatialindex.github.com instead (I have not verified it can handle spatial objects and not just points though).Kelleher
T
1

Build a segment Voronoi diagram, then take proximity candidates from neighbouring cells.

Tael answered 18/3, 2013 at 17:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.