From: Jiri Vlasak Date: Thu, 30 Jan 2020 10:43:15 +0000 (+0100) Subject: Copy kd tree from 2D kd tree X-Git-Tag: v0.4.0~15^2~3 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/hubacji1/rrts.git/commitdiff_plain/7b5386148cc61d49a688ad6dcc0ba36615e472dc Copy kd tree from 2D kd tree --- diff --git a/CMakeLists.txt b/CMakeLists.txt index dd0d21d..4cac376 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/README.md b/README.md index 7d84f1e..db739af 100644 --- 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), diff --git a/api/rrtext.h b/api/rrtext.h index 2081c56..128fe0c 100644 --- a/api/rrtext.h +++ b/api/rrtext.h @@ -13,8 +13,38 @@ #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 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 index 0000000..9544db6 --- /dev/null +++ b/src/rrtext8.cc @@ -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 RRTExt8::nv(RRTNode &t) +{ + std::vector nv; + return nv; +}