World Builder  1.1.0-pre
A geodynamic initial conditions generator
kd_tree.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018-2024 by the authors of the World Builder code.
3 
4  This file is part of the World Builder.
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef KD_TREE_H
21 #define KD_TREE_H
22 
23 #include <vector>
24 #include <cstddef>
25 #include <iostream>
26 #include <limits>
27 
28 #include "world_builder/assert.h"
29 #include "world_builder/point.h"
30 
31 namespace WorldBuilder
32 {
33  namespace KDTree
34  {
40  {
41  size_t index;
42  double distance;
43  };
44 
45 
51  {
52  size_t min_index;
53  double min_distance;
54  std::vector<IndexDistance> vector;
55  };
56 
60  struct Node
61  {
62  size_t index;
63  double x;
64  double y;
65 
66  Node(size_t index_, double x_, double y_)
67  :
68  index(index_),
69  x(x_),
70  y(y_)
71  {}
72 
73 
77  inline
78  const double &operator[](const bool y_axis) const
79  {
80  WBAssert(std::fabs((y_axis ? y : x) - *(&x+y_axis)) < std::numeric_limits<double>::epsilon(),
81  "Internal error: y_axis=" << y_axis << ", x=" << x << ", y=" << y <<", *(&x+y_axis)=" << *(&x+y_axis)
82  << ", ((bool)y_axis ? x : y) - *(&x+y_axis)=" << fabs((y_axis ? x : y) - *(&x+y_axis)));
83  return *(&x+y_axis);
84  }
85  };
86 
87  class KDTree
88  {
89  public:
93  KDTree() = default;
97  KDTree(const std::vector<Node> point_list);
98 
103  void create_tree(const size_t left,
104  const size_t right,
105  const bool x_axis);
106 
110  const std::vector<Node> &get_nodes() const;
111 
116  IndexDistance find_closest_point(const Point<2> &check_point) const;
117 
118 
119 
130  IndexDistances find_closest_points(const Point<2> &check_point) const;
131 
132 
133  private:
139  void find_closest_point_recursive(const Point<2> &check_point,
140  const size_t left,
141  const size_t right,
142  const bool y_axis,
143  IndexDistance &index_distance) const;
144 
145 
151  void find_closest_points_recursive(const Point<2> &check_point,
152  const size_t left,
153  const size_t right,
154  const bool y_axis,
155  IndexDistances &index_distances) const;
156 
157  std::vector<Node> nodes;
158  };
159  }
160 }
161 #endif
std::vector< Node > nodes
Definition: kd_tree.h:157
const double & operator[](const bool y_axis) const
Definition: kd_tree.h:78
std::vector< IndexDistance > vector
Definition: kd_tree.h:54
Node(size_t index_, double x_, double y_)
Definition: kd_tree.h:66
#define WBAssert(condition, message)
Definition: assert.h:27