octomap 1.5.0
include/octomap/OcTreeKey.h
Go to the documentation of this file.
00001 #ifndef OCTOMAP_OCTREE_KEY_H
00002 #define OCTOMAP_OCTREE_KEY_H
00003 
00004 // $Id: OcTreeKey.h 416 2012-08-27 12:43:01Z ahornung $
00005 
00014 /*
00015  * Copyright (c) 2010, K. M. Wurm, A. Hornung, University of Freiburg
00016  * All rights reserved.
00017  *
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions are met:
00020  *
00021  *     * Redistributions of source code must retain the above copyright
00022  *       notice, this list of conditions and the following disclaimer.
00023  *     * Redistributions in binary form must reproduce the above copyright
00024  *       notice, this list of conditions and the following disclaimer in the
00025  *       documentation and/or other materials provided with the distribution.
00026  *     * Neither the name of the University of Freiburg nor the names of its
00027  *       contributors may be used to endorse or promote products derived from
00028  *       this software without specific prior written permission.
00029  *
00030  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00031  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00034  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00035  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00036  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00037  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00038  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00039  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00040  * POSSIBILITY OF SUCH DAMAGE.
00041  */
00042 
00043 #include <assert.h>
00044 #ifdef __GNUC__
00045   #include <tr1/unordered_set>
00046 #include <tr1/unordered_map>
00047 #else
00048   #include <unordered_set>
00049 #include <unordered_map>
00050 #endif
00051 
00052 namespace octomap {
00053 
00059   class OcTreeKey {
00060     
00061   public:  
00062     OcTreeKey () {}
00063     OcTreeKey (unsigned short int a, unsigned short int b, unsigned short int c)
00064       { k[0] = a; k[1] = b; k[2] = c; }
00065     OcTreeKey(const OcTreeKey& other){
00066       k[0] = other.k[0]; k[1] = other.k[1]; k[2] = other.k[2];
00067     }
00068     bool operator== (const OcTreeKey &other) const { 
00069       return ((k[0] == other[0]) && (k[1] == other[1]) && (k[2] == other[2]));
00070     }
00071     bool operator!= (const OcTreeKey &other) const {
00072       return( (k[0] != other[0]) || (k[1] != other[1]) || (k[2] != other[2]) );
00073     }
00074     OcTreeKey& operator=(const OcTreeKey& other){
00075       k[0] = other.k[0]; k[1] = other.k[1]; k[2] = other.k[2];
00076       return *this;
00077     }
00078     const unsigned short int& operator[] (unsigned int i) const { 
00079       return k[i];
00080     }
00081     unsigned short int& operator[] (unsigned int i) { 
00082       return k[i];
00083     }
00084 
00085     unsigned short int k[3];
00086 
00088     struct KeyHash{
00089       size_t operator()(const OcTreeKey& key) const{
00090         // a hashing function 
00091         return key.k[0] + 1337*key.k[1] + 345637*key.k[2];
00092       }
00093     };
00094     
00095   };
00096   
00103   typedef std::tr1::unordered_set<OcTreeKey, OcTreeKey::KeyHash> KeySet;
00104 
00110   typedef std::tr1::unordered_map<OcTreeKey, bool, OcTreeKey::KeyHash> KeyBoolMap;
00111 
00112 
00113   class KeyRay {
00114   public:
00115     
00116     KeyRay () {
00117       ray.resize(100000);
00118       reset();
00119     }
00120     void reset() {
00121       end_of_ray = begin();
00122     }
00123     void addKey(OcTreeKey& k) {
00124       assert(end_of_ray != ray.end());
00125       *end_of_ray = k;
00126       end_of_ray++;
00127     }
00128 
00129     unsigned int size() const { return end_of_ray - ray.begin(); }
00130     unsigned int sizeMax() const { return 100000; }
00131 
00132     typedef std::vector<OcTreeKey>::iterator iterator;
00133     typedef std::vector<OcTreeKey>::const_iterator const_iterator;
00134     typedef std::vector<OcTreeKey>::reverse_iterator reverse_iterator;
00135     
00136     iterator begin() { return ray.begin(); }
00137     iterator end() { return end_of_ray; }
00138     const_iterator begin() const { return ray.begin(); }
00139     const_iterator end() const   { return end_of_ray; }
00140 
00141     reverse_iterator rbegin() { return (reverse_iterator) end_of_ray; }
00142     reverse_iterator rend() { return ray.rend(); }
00143 
00144   public:
00145 
00146     std::vector<OcTreeKey> ray;
00147     std::vector<OcTreeKey>::iterator end_of_ray;
00148   };
00149 
00159   inline void computeChildKey (const unsigned int& pos, const unsigned short int& center_offset_key,
00160                                           const OcTreeKey& parent_key, OcTreeKey& child_key) {
00161     
00162     if (pos & 1) child_key[0] = parent_key[0] + center_offset_key;
00163     else         child_key[0] = parent_key[0] - center_offset_key - (center_offset_key ? 0 : 1);
00164     // y-axis
00165     if (pos & 2) child_key[1] = parent_key[1] + center_offset_key;
00166     else         child_key[1] = parent_key[1] - center_offset_key - (center_offset_key ? 0 : 1);
00167     // z-axis
00168     if (pos & 4) child_key[2] = parent_key[2] + center_offset_key;
00169     else         child_key[2] = parent_key[2] - center_offset_key - (center_offset_key ? 0 : 1);
00170   }
00171   
00173   inline unsigned char computeChildIdx(const OcTreeKey& key, int depth){
00174     unsigned char pos = 0;
00175     if (key.k[0] & (1 << depth)) pos += 1;
00176     if (key.k[1] & (1 << depth)) pos += 2;
00177     if (key.k[2] & (1 << depth)) pos += 4;
00178     return pos;
00179   }
00180 
00188   inline OcTreeKey computeIndexKey(unsigned short int level, const OcTreeKey& key) {
00189     unsigned short int mask = 65535 << level;
00190     OcTreeKey result = key;
00191     result[0] &= mask;
00192     result[1] &= mask;
00193     result[2] &= mask;
00194     return result;
00195   }
00196 
00197 } // namespace
00198 
00199 #endif