snark
voxel_grid.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SNARK_PERCEPTION_VOXELGRID_HEADER_GUARD
20 #define SNARK_PERCEPTION_VOXELGRID_HEADER_GUARD
21 
22 #include <cmath>
23 #include <map>
24 #include <boost/none_t.hpp>
25 #include <Eigen/Core>
26 #include <boost/optional.hpp>
27 #include <snark/math/interval.h>
28 #include <snark/point_cloud/impl/pin_screen.h>
29 
30 namespace snark {
31 
36 template < typename V = boost::none_t, typename P = Eigen::Vector3d >
37 class voxel_grid : public pin_screen< V >
38 {
39  public:
40  typedef V voxel_type;
41  typedef P point_type;
42  typedef typename pin_screen< V >::index_type index_type;
43  typedef typename pin_screen< V >::size_type size_type;
44  typedef typename pin_screen< V >::column_type column_type;
46 
52  , const point_type& resolution
53  , bool adjusted = false );
54 
56  const interval_type& extents() const;
57 
59  const point_type& resolution() const;
60 
62  index_type index_of( const point_type& p ) const;
63 
65  bool covers( const point_type& p ) const;
66 
68  voxel_type* touch_at( const point_type& d );
69 
71  void erase_at( const point_type& p );
72 
74  point_type origin( const index_type& i ) const;
75 
77  point_type origin_at( const point_type& p ) const;
78 
80  const column_type* column( const point_type& p ) const;
81  //column_type* column( const point_type& p ); // no non-const class in pin_screen for now
82 
87 
88  private:
89  interval_type extents_;
90  point_type resolution_;
91 };
92 
93 namespace detail {
94 
95 template < typename P >
97 {
98  return adjusted ? math::closed_interval< typename P::Scalar, P::RowsAtCompileTime >( e.min() - r / 2, e.max() + r / 2 ) : e;
99 }
100 
101 template < typename P >
102 inline static Eigen::Matrix< std::size_t, 1, 2 > size( const math::closed_interval< typename P::Scalar, P::RowsAtCompileTime >& e, const P& r, bool adjusted = true )
103 {
104  math::closed_interval< typename P::Scalar, P::RowsAtCompileTime > f = extents( e, r, adjusted );
105  P diff = f.max() - f.min();
106  return Eigen::Matrix< std::size_t, 1, 2 >( std::ceil( diff.x() / r.x() ), std::ceil( diff.y() / r.y() ) );
107 }
108 
109 } // namespace detail {
110 
111 template < typename V, typename P >
113  , const typename voxel_grid< V, P >::point_type& resolution
114  , bool adjusted )
115  : pin_screen< V >( detail::size( extents, resolution, adjusted ) )
116  , extents_( detail::extents( extents, resolution, adjusted ) )
117  , resolution_( resolution )
118 {
119 }
120 
121 template < typename V, typename P >
122 inline const typename voxel_grid< V, P >::interval_type& voxel_grid< V, P >::extents() const { return extents_; }
123 
124 template < typename V, typename P >
125 inline const P& voxel_grid< V, P >::resolution() const { return resolution_; }
126 
127 template < typename V, typename P >
128 inline typename voxel_grid< V, P >::index_type voxel_grid< V, P >::index_of( const P& p ) const
129 {
130  return index_type( std::floor( ( p.x() - extents_.min().x() ) / resolution_.x() )
131  , std::floor( ( p.y() - extents_.min().y() ) / resolution_.y() )
132  , std::floor( ( p.z() - extents_.min().z() ) / resolution_.z() ) );
133 }
134 
135 template < typename V, typename P >
136 inline bool voxel_grid< V, P >::covers( const P& p ) const
137 {
138  return extents_.contains( p );
139 }
140 
141 template < typename V, typename P >
142 inline V* voxel_grid< V, P >::touch_at( const P& p )
143 {
144  if( !covers( p ) ) { return NULL; }
145  const index_type& i = index_of( p );
146  return &pin_screen< V >::touch( i );
147 }
148 
149 template < typename V, typename P >
150 inline void voxel_grid< V, P >::erase_at( const P& point )
151 {
152  if( !covers( point ) ) { return; }
153  pin_screen< V >::erase( index_of( point ) );
154 }
155 
156 template < typename V, typename P >
157 inline P voxel_grid< V, P >::origin( const index_type& i ) const
158 {
159  P p( resolution_[0] * i[0], resolution_[1] * i[1], resolution_[2] * i[2] );
160  return extents_.min() + p;
161 }
162 
163 template < typename V, typename P >
164 inline P voxel_grid< V, P >::origin_at( const point_type& p ) const
165 {
166  return origin( index_of( p ) );
167 }
168 
169 template < typename V, typename P >
170 const typename voxel_grid< V, P >::column_type* voxel_grid< V, P >::column( const point_type& p ) const
171 {
172  if( !covers( p ) ) { return NULL; }
173  index_type index = index_of( p );
174  return &this->pin_screen< V >::column( index.x(), index.y() );
175 }
176 
177 // template < typename V, typename P >
178 // typename voxel_grid< V, P >::column_type* voxel_grid< V, P >::column( const point_type& p )
179 // {
180 // if( !covers( p ) ) { return NULL; }
181 // index i = index_of( p );
182 // return &( this->column( i[0], i[1] ) );
183 // }
184 
185 } // namespace snark {
186 
187 #endif // SNARK_PERCEPTION_VOXELGRID_HEADER_GUARD