]> rtime.felk.cvut.cz Git - hubacji1/rrts.git/commitdiff
Copy kd tree from 2D kd tree
authorJiri Vlasak <hubacji1@fel.cvut.cz>
Thu, 30 Jan 2020 10:43:15 +0000 (11:43 +0100)
committerJiri Vlasak <hubacji1@fel.cvut.cz>
Thu, 30 Jan 2020 10:43:15 +0000 (11:43 +0100)
CMakeLists.txt
README.md
api/rrtext.h
src/rrtext8.cc [new file with mode: 0644]

index dd0d21dc72b52405252ac53024efc4a8e91dd3ad..4cac3768984d1b0391ba612756fe762b4a853704 100644 (file)
@@ -15,6 +15,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/api)
 
 add_library(rrts SHARED
         src/rrts.cc
+        src/rrtext8.cc
         src/rrtext7.cc
         src/rrtext6.cc
         src/rrtext5.cc
index 7d84f1e6e1a94d7f0647beac4bcef48fe15cbd32..db739af0b6f0969c2dcef181795fa807f6ccd7c2 100644 (file)
--- a/README.md
+++ b/README.md
@@ -34,7 +34,8 @@ and upgrades to RRT, *extensions* are declared in `rrtext.h` and implemented in
 
 ## Implemented extensions
 There is a list of implemented extensions and what they include:
-- `rrtext7.cc`: [K-d tree][] for node storage.
+- `rrtext8.cc`: 3D [K-d tree][] for node storage.
+- `rrtext7.cc`: 2D [K-d tree][] for node storage.
 - `rrtext6.cc`: Reeds and Shepp for both -- building and search costs,
 - `rrtext5.cc`: different cost for building (Reeds and Shepp) and searching
   (Euclidean distance),
index 2081c56eb99c25cff88a2e86fcdca36020c5f7f7..128fe0c49334d7674b06ee454569d95f5439810a 100644 (file)
 #define GRID_MAX_XI ((unsigned int) floor(GRID_WIDTH / GRID)) // min is 0
 #define GRID_MAX_YI ((unsigned int) floor(GRID_HEIGHT / GRID)) // min is 0
 
-// ext7
-#define MAX_DIM 2
+/*! \brief Use k-d tree data structure to store RRT nodes.
+
+This approach speeds up the search process for the nearest neighbor and
+the near vertices procedures. This extension implements 3D K-d tree.
+
+\see https://en.wikipedia.org/wiki/K-d_tree
+*/
+class RRTExt8 : public virtual RRTS {
+        private:
+                class KdNode {
+                        private:
+                                RRTNode *node_ = nullptr;
+                                KdNode *left_ = nullptr;
+                                KdNode *right_ = nullptr;
+                        public:
+                                // getter, setter
+                                RRTNode *node() const { return this->node_; }
+                                KdNode *&left() { return this->left_; }
+                                KdNode *&right() { return this->right_; }
+                                KdNode(RRTNode *n);
+                };
+                KdNode *kdroot_ = nullptr;
+                void delete_kd_nodes(KdNode *n);
+                void store_node(RRTNode *n, KdNode *&r, int l);
+                void nn(RRTNode *&n, RRTNode &t, KdNode *r, int l, double &d);
+        public:
+                void init();
+                void deinit();
+                void store_node(RRTNode n);
+                RRTNode *nn(RRTNode &t);
+                std::vector<RRTNode *> nv(RRTNode &t);
+};
 
 /*! \brief Use k-d tree data structure to store RRT nodes.
 
diff --git a/src/rrtext8.cc b/src/rrtext8.cc
new file mode 100644 (file)
index 0000000..9544db6
--- /dev/null
@@ -0,0 +1,91 @@
+#include "rrtext.h"
+
+RRTExt8::KdNode::KdNode(RRTNode *n)
+        : node_(n)
+        , left_(nullptr)
+        , right_(nullptr)
+{
+}
+
+void RRTExt8::delete_kd_nodes(KdNode *n)
+{
+        if (!n)
+                return;
+        if (n->left() != nullptr)
+                delete_kd_nodes(n->left());
+        if (n->right() != nullptr)
+                delete_kd_nodes(n->right());
+        delete n;
+}
+
+void RRTExt8::store_node(RRTNode *n, KdNode *&r, int l)
+{
+        if (r == nullptr)
+                r = new KdNode(n);
+        else if (l % 2 == 0 && n->x() < r->node()->x())
+                store_node(n, r->left(), l + 1);
+        else if (l % 2 == 0)
+                store_node(n, r->right(), l + 1);
+        else if (l % 2 == 1 && n->y() < r->node()->y())
+                store_node(n, r->left(), l + 1);
+        else
+                store_node(n, r->right(), l + 1);
+}
+
+void RRTExt8::nn(RRTNode *&n, RRTNode &t, KdNode *r, int l, double &d)
+{
+        if (r == nullptr)
+                return;
+        if (this->cost_search(*r->node(), t) < d) {
+                n = r->node();
+                d = this->cost_search(*r->node(), t);
+        }
+        if (l % 2 == 0 && t.x() < r->node()->x()) {
+                nn(n, t, r->left(), l + 1, d);
+                if (r->node()->x() - t.x() < d)
+                        nn(n, t, r->right(), l + 1, d);
+        } else if (l % 2 == 0) {
+                nn(n, t, r->right(), l + 1, d);
+                if (t.x() - r->node()->x() < d)
+                        nn(n, t, r->left(), l + 1, d);
+        } else if (l % 2 == 1 && t.y() < r->node()->y()) {
+                nn(n, t, r->left(), l + 1, d);
+                if (r->node()->y() - t.y() < d)
+                        nn(n, t, r->right(), l + 1, d);
+        } else {
+                nn(n, t, r->right(), l + 1, d);
+                if (t.y() - r->node()->y() < d)
+                        nn(n, t, r->left(), l + 1, d);
+        }
+}
+
+// API
+void RRTExt8::init()
+{
+}
+
+void RRTExt8::deinit()
+{
+        this->delete_kd_nodes(this->kdroot_);
+}
+
+void RRTExt8::store_node(RRTNode n)
+{
+        RRTS::store_node(n);
+        RRTNode *sn = &this->nodes().back();
+        this->store_node(sn, this->kdroot_, 0);
+}
+
+RRTNode *RRTExt8::nn(RRTNode &t)
+{
+        RRTNode *n = &this->nodes().front();
+        double d = 9999;
+        this->nn(n, t, this->kdroot_, 0, d);
+        return n;
+}
+
+std::vector<RRTNode *> RRTExt8::nv(RRTNode &t)
+{
+        std::vector<RRTNode *> nv;
+        return nv;
+}