c++ data-structures kdtree r-tree

c++ - Manera eficiente de manejar segmentos de línea 2D



data-structures kdtree (3)

Construya un diagrama de segmentos de Voronoi , luego tome candidatos de proximidad de las celdas vecinas.

Estoy teniendo un gran conjunto de segmentos de línea 2D. Así que sé; Número de línea, Begin (X, Y, Z) y End (x, Y, Z) de cada segmento de línea. Quiero obtener segmentos de líneas de proximidad para un segmento de línea determinado. Del mismo modo para todos.

Para encontrar la proximidad puedo aplicar esto

Si digo mis datos, es como;

Entonces, al final quiero obtener líneas de proximidad como vector para cada segmento de línea . Escuché que este tipo de vector de vector se puede tomar con estructuras de datos de árbol r. Estaba buscándolo pero aún no pude encontrar el relevante para mí. También miré en opencv, hay un r-tree pero dice algo sobre clasificador y fase de entrenamiento ... así que, supongo que no me queda bien.

¿Alguien puede saber cómo obtener la línea no, luego sus líneas vecinas para ex;

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

2 = {1,4,5,6}

3 = {...} .. .. este tipo de vector de vector usando r-tree.

Lo sé, podemos obtener este tipo de vectores usando kd-tree. Pero está diseñado para los datos de puntos. Entonces, es difícil usar kd-tree para este caso, creo. cualquier ayuda por favor, gracias.


Sí, los árboles R pueden hacer esto . Están diseñados para objetos arbitrarios con extensión espacial, no se limitan a datos de puntos. En realidad, algunos de los ejemplos más antiguos usaban polígonos .

¿Has intentado usarlos?


Teóricamente, la búsqueda de los Segmentos más cercanos debería ser posible utilizando cualquier tipo de estructura de datos de partición espacial o índice espacial. Muy a menudo, la interfaz de dicho índice espacial permite almacenar Cajas (AABB) o Puntos, por lo que en estos casos se vería forzado a almacenar Cajas de Segmentos delimitadoras y luego, después de consultar los Casilleros más cercanos, verificar nuevamente los Segmentos correspondientes. Sin embargo, es posible indexar Segmentos directamente. Por ejemplo, en el caso de kd-tree sería una versión que contiene nodos internos que definen planos de división y hojas que almacenan segmentos.

Boost.Geometry R-tree admite segmentos en Boost versión 1.56.0 y superior. A continuación se muestra el ejemplo de 2d segmentos que usan esta implementación de índice espacial:

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

En caso de que necesitara TODOS los Segmentos que están más cerca que algún umbral, podría usar consultas iterativas ( ejemplo ).