00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: itkIndex.h,v $ 00005 Language: C++ 00006 Date: $Date: 2006/04/13 17:57:25 $ 00007 Version: $Revision: 1.52 $ 00008 00009 Copyright (c) Insight Software Consortium. All rights reserved. 00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 #ifndef __itkIndex_h 00018 #define __itkIndex_h 00019 00020 #include "itkMacro.h" 00021 #include "itkOffset.h" 00022 #include "itkSize.h" 00023 00024 #include <memory> 00025 00026 #include "itkExceptionObject.h" 00027 00028 namespace itk 00029 { 00030 00031 namespace Functor 00032 { 00033 template<unsigned int VIndexDimension> class IndexLexicographicCompare; 00034 } 00035 00065 template<unsigned int VIndexDimension=2> 00066 class Index { 00067 public: 00069 typedef Index Self; 00070 00072 typedef Index<VIndexDimension> IndexType; 00073 typedef long IndexValueType; 00074 00076 static unsigned int GetIndexDimension() { return VIndexDimension; } 00077 00079 typedef Size<VIndexDimension> SizeType; 00080 00082 typedef Offset<VIndexDimension> OffsetType; 00083 typedef typename OffsetType::OffsetValueType OffsetValueType; 00084 00086 typedef Functor::IndexLexicographicCompare<VIndexDimension> LexicographicCompare; 00087 00089 const Self 00090 operator+(const SizeType &size) const 00091 { 00092 Self result; 00093 for (unsigned int i=0; i < VIndexDimension; i++) 00094 { result[i] = m_Index[i] + static_cast<IndexValueType>(size[i]); } 00095 return result; 00096 } 00098 00100 const Self & 00101 operator+=(const SizeType &size) 00102 { 00103 for (unsigned int i=0; i < VIndexDimension; i++) 00104 { m_Index[i] += static_cast<IndexValueType>(size[i]); } 00105 return *this; 00106 } 00108 00110 const Self 00111 operator-(const SizeType &size) const 00112 { 00113 Self result; 00114 for (unsigned int i=0; i < VIndexDimension; i++) 00115 { result[i] = m_Index[i] - static_cast<IndexValueType>(size[i]); } 00116 return result; 00117 } 00119 00121 const Self & 00122 operator-=(const SizeType &size) 00123 { 00124 for (unsigned int i=0; i < VIndexDimension; i++) 00125 { m_Index[i] -= static_cast<IndexValueType>(size[i]); } 00126 return *this; 00127 } 00129 00131 const Self 00132 operator+(const OffsetType &offset) const 00133 { 00134 Self result; 00135 for (unsigned int i=0; i < VIndexDimension; i++) 00136 { result[i] = m_Index[i] + offset[i]; } 00137 return result; 00138 } 00140 00142 const Self & 00143 operator+=(const OffsetType &offset) 00144 { 00145 for (unsigned int i=0; i < VIndexDimension; i++) 00146 { m_Index[i] += offset[i]; } 00147 return *this; 00148 } 00150 00152 const Self & 00153 operator-=(const OffsetType &offset) 00154 { 00155 for (unsigned int i=0; i < VIndexDimension; i++) 00156 { m_Index[i] -= offset[i]; } 00157 return *this; 00158 } 00160 00162 const Self 00163 operator-(const OffsetType &off) const 00164 { 00165 Self result; 00166 for (unsigned int i=0; i < VIndexDimension; i++) 00167 { result[i] = m_Index[i] - off.m_Offset[i]; } 00168 return result; 00169 } 00171 00173 const OffsetType 00174 operator-(const Self &vec) const 00175 { 00176 OffsetType result; 00177 for (unsigned int i=0; i < VIndexDimension; i++) 00178 { result[i] = m_Index[i] - vec.m_Index[i]; } 00179 return result; 00180 } 00182 00185 const Self 00186 operator*(const SizeType &vec) const 00187 { 00188 Self result; 00189 for (unsigned int i=0; i < VIndexDimension; i++) 00190 { result[i] = m_Index[i] * static_cast<IndexValueType>(vec.m_Size[i]); } 00191 return result; 00192 } 00194 00196 bool 00197 operator==(const Self &vec) const 00198 { 00199 bool same=true; 00200 for (unsigned int i=0; i < VIndexDimension && same; i++) 00201 { same = (m_Index[i] == vec.m_Index[i]); } 00202 return same; 00203 } 00205 00207 bool 00208 operator!=(const Self &vec) const 00209 { 00210 bool same=true; 00211 for (unsigned int i=0; i < VIndexDimension && same; i++) 00212 { same = (m_Index[i] == vec.m_Index[i]); } 00213 return !same; 00214 } 00216 00219 IndexValueType & operator[](unsigned int dim) 00220 { return m_Index[dim]; } 00221 00225 IndexValueType operator[](unsigned int dim) const 00226 { return m_Index[dim]; } 00227 00230 const IndexValueType *GetIndex() const { return m_Index; }; 00231 00236 void SetIndex(const IndexValueType val[VIndexDimension]) 00237 { memcpy(m_Index, val, sizeof(IndexValueType)*VIndexDimension); } 00238 00245 void SetElement(unsigned long element, IndexValueType val ) 00246 { m_Index[ element ] = val; } 00247 00254 IndexValueType GetElement( unsigned long element ) 00255 { return m_Index[ element ]; } 00256 00260 static Self GetBasisIndex(unsigned int dim); 00261 00264 void Fill(IndexValueType value) 00265 { for(unsigned int i=0;i < VIndexDimension; ++i) m_Index[i] = value; } 00266 00272 IndexValueType m_Index[VIndexDimension]; 00273 00274 }; 00275 00276 namespace Functor 00277 { 00285 template<unsigned int VIndexDimension> 00286 class IndexLexicographicCompare 00287 { 00288 public: 00289 bool operator()(Index<VIndexDimension> const& l, 00290 Index<VIndexDimension> const& r) const 00291 { 00292 for(unsigned int i=0; i < VIndexDimension; ++i) 00293 { 00294 if(l.m_Index[i] < r.m_Index[i]) 00295 { 00296 return true; 00297 } 00298 else if(l.m_Index[i] > r.m_Index[i]) 00299 { 00300 return false; 00301 } 00302 } 00303 return false; 00304 } 00305 }; 00306 } 00307 00308 template<unsigned int VIndexDimension> 00309 Index<VIndexDimension> 00310 Index<VIndexDimension> 00311 ::GetBasisIndex(unsigned int dim) 00312 { 00313 Self ind; 00314 00315 memset(ind.m_Index, 0, sizeof(IndexValueType)*VIndexDimension); 00316 ind.m_Index[dim] = 1; 00317 return ind; 00318 } 00319 00320 template<unsigned int VIndexDimension> 00321 std::ostream & operator<<(std::ostream &os, const Index<VIndexDimension> &ind) 00322 { 00323 os << "["; 00324 for (unsigned int i=0; i+1 < VIndexDimension; ++i) 00325 { 00326 os << ind[i] << ", "; 00327 } 00328 if (VIndexDimension >= 1) 00329 { 00330 os << ind[VIndexDimension-1]; 00331 } 00332 os << "]"; 00333 return os; 00334 } 00335 00336 } // end namespace itk 00337 00338 #endif 00339