NiHu  2.0
bounding_box.hpp
Go to the documentation of this file.
1 
7 #ifndef NIHU_BOUNDING_BOX_HPP_INCLUDED
8 #define NIHU_BOUNDING_BOX_HPP_INCLUDED
9 
10 #include <Eigen/Dense>
11 
12 #include <algorithm>
13 #include <cmath>
14 #include <cstddef>
15 #include <iostream>
16 
17 namespace NiHu
18 {
19 namespace fmm
20 {
29 template <size_t Dim, class Scalar = double>
31 {
32 public:
34  static size_t const dimension = Dim;
36  using scalar_t = Scalar;
38  using location_t = Eigen::Matrix<scalar_t, dimension, 1>;
39 
45  location_t const &center = location_t::Zero(),
46  scalar_t diameter = 2.0
47  )
48  : m_center(center)
49  , m_diameter(diameter)
50  {
51  }
52 
59  template <class NodesDerived>
60  explicit bounding_box(Eigen::DenseBase<NodesDerived> const &nodes)
61  : m_diameter(0.)
62  {
63  for (size_t d = 0; d < dimension; ++d)
64  {
65  scalar_t a = nodes.row(d).minCoeff();
66  scalar_t b = nodes.row(d).maxCoeff();
67  m_center(d) = (a + b) / 2.;
68  m_diameter = std::max(m_diameter, b-a);
69  }
70  }
71 
75  location_t const &get_center(void) const
76  {
77  return m_center;
78  }
79 
83  void set_center(location_t const &c)
84  {
85  m_center = c;
86  }
87 
91  scalar_t get_diameter(void) const
92  {
93  return m_diameter;
94  }
95 
99  void set_diameter(scalar_t const &d)
100  {
101  m_diameter = d;
102  }
103 
108  bounding_box get_child(size_t idx) const
109  {
110  location_t offset = idx2dist(idx) * (m_diameter / 4.0);
111  return bounding_box(m_center + offset, m_diameter / 2.0);
112  }
113 
124  bool is_adjacent(bounding_box const &other, double tol = 1e-3) const
125  {
126  location_t dist = other.get_center() - this->get_center();
127  auto D = (this->get_diameter() + other.get_diameter()) / 2.;
128  for (auto d = 0; d < dimension; ++d)
129  if (std::abs(dist(d)) > D * (1.0 + tol))
130  return false;
131  return true;
132  }
133 
139  static unsigned dist2idx(location_t const &child, location_t const &parent)
140  {
141  auto idx = 0;
142  for (auto d = 0; d < dimension; ++d)
143  if (child(d) > parent(d))
144  idx |= (1 << d);
145  return idx;
146  }
147 
152  static location_t idx2dist(size_t idx)
153  {
154  if (idx >= (1 << dimension))
155  throw std::invalid_argument("bounding_box child index too large");
156 
157  location_t dst = location_t::Zero();
158  for (auto d = 0; d < dimension; ++d)
159  dst(d) = ((idx >> d) & 1) == 1 ? 1.0 : -1.0;
160  return dst;
161  }
162 
166  void print_debug(std::ostream &os = std::cout) const
167  {
168  os << "(" << this->get_center().transpose() << ") " << this->get_diameter();
169  }
170 
171 private:
172  location_t m_center;
173  scalar_t m_diameter;
174 };
175 
183 template <size_t Dim, class T>
184 std::ostream &operator<<(std::ostream &os, bounding_box<Dim, T> const &bb)
185 {
186  bb.print_debug(os);
187  return os;
188 }
189 } // end of namespace fmm
190 } // end of namespace NiHu
191 
192 #endif /* NIHU_BOUNDING_BOX_HPP_INCLUDED */
NiHu::operator<<
std::ostream & operator<<(std::ostream &os, const quadrature_base< Derived > &Q)
print a quadrature into an ouput stream
Definition: quadrature.hpp:317
NiHu::fmm::bounding_box::bounding_box
bounding_box(Eigen::DenseBase< NodesDerived > const &nodes)
constructor from a set of contained nodes
Definition: bounding_box.hpp:60
NiHu::fmm::bounding_box< dimension, double >::location_t
Eigen::Matrix< scalar_t, dimension, 1 > location_t
the location type in the bounding box
Definition: bounding_box.hpp:38
NiHu::fmm::bounding_box::get_child
bounding_box get_child(size_t idx) const
get a child box
Definition: bounding_box.hpp:108
NiHu::fmm::bounding_box::dimension
static const size_t dimension
template parameter as nested constant
Definition: bounding_box.hpp:34
NiHu::fmm::bounding_box< dimension, double >::scalar_t
double scalar_t
template argument as nested type
Definition: bounding_box.hpp:36
NiHu::fmm::bounding_box::set_center
void set_center(location_t const &c)
set the center
Definition: bounding_box.hpp:83
NiHu::fmm::bounding_box::print_debug
void print_debug(std::ostream &os=std::cout) const
print debug information to an output stream
Definition: bounding_box.hpp:166
NiHu::fmm::bounding_box::set_diameter
void set_diameter(scalar_t const &d)
set the diameter
Definition: bounding_box.hpp:99
NiHu::fmm::bounding_box::get_center
const location_t & get_center(void) const
return center
Definition: bounding_box.hpp:75
NiHu::fmm::bounding_box::is_adjacent
bool is_adjacent(bounding_box const &other, double tol=1e-3) const
determine if a box is adjacent
Definition: bounding_box.hpp:124
NiHu::fmm::bounding_box
multidimensional square bounding box
Definition: bounding_box.hpp:30
NiHu::fmm::bounding_box::dist2idx
static unsigned dist2idx(location_t const &child, location_t const &parent)
convert parent-to-child direction to child index
Definition: bounding_box.hpp:139
NiHu::fmm::bounding_box::idx2dist
static location_t idx2dist(size_t idx)
convert child index to parent-to-child direction
Definition: bounding_box.hpp:152
NiHu::fmm::bounding_box::get_diameter
scalar_t get_diameter(void) const
return diameter
Definition: bounding_box.hpp:91
NiHu::fmm::bounding_box::bounding_box
bounding_box(location_t const &center=location_t::Zero(), scalar_t diameter=2.0)
constructor from center and diameter
Definition: bounding_box.hpp:44