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 
141  static unsigned dist2idx(location_t const &child, location_t const &parent)
142  {
143  auto idx = 0;
144  for (auto d = 0; d < dimension; ++d)
145  if (child(d) > parent(d))
146  idx |= (1 << d);
147  return idx;
148  }
149 
154  static location_t idx2dist(size_t idx)
155  {
156  if (idx >= (1 << dimension))
157  throw std::invalid_argument("bounding_box child index too large");
158 
159  location_t dst = location_t::Zero();
160  for (auto d = 0; d < dimension; ++d)
161  dst(d) = ((idx >> d) & 1) == 1 ? 1.0 : -1.0;
162  return dst;
163  }
164 
168  void print_debug(std::ostream &os = std::cout) const
169  {
170  os << "(" << this->get_center().transpose() << ") " << this->get_diameter();
171  }
172 
173 private:
174  location_t m_center;
175  scalar_t m_diameter;
176 };
177 
185 template <size_t Dim, class T>
186 std::ostream &operator<<(std::ostream &os, bounding_box<Dim, T> const &bb)
187 {
188  bb.print_debug(os);
189  return os;
190 }
191 } // end of namespace fmm
192 } // end of namespace NiHu
193 
194 #endif /* NIHU_BOUNDING_BOX_HPP_INCLUDED */
NiHu::fmm::bounding_box::idx2dist
static location_t idx2dist(size_t idx)
convert child index to parent-to-child direction
Definition: bounding_box.hpp:154
NiHu::fmm::bounding_box::dist2idx
static unsigned dist2idx(location_t const &child, location_t const &parent)
convert parent-to-child direction to child index This functionality is used to precompute M2M and L2L...
Definition: bounding_box.hpp:141
NiHu::fmm::bounding_box
multidimensional square bounding box
Definition: bounding_box.hpp:30
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::print_debug
void print_debug(std::ostream &os=std::cout) const
print debug information to an output stream
Definition: bounding_box.hpp:168
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::get_center
const location_t & get_center(void) const
return center
Definition: bounding_box.hpp:75
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::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
static const size_t dimension
template parameter as nested constant
Definition: bounding_box.hpp:34
NiHu::fmm::bounding_box::get_diameter
scalar_t get_diameter(void) const
return diameter
Definition: bounding_box.hpp:91
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< 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::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
NiHu::fmm::bounding_box::set_center
void set_center(location_t const &c)
set the center
Definition: bounding_box.hpp:83