00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkPhasedArray3DSpecialCoordinatesImage_h
00018 #define __itkPhasedArray3DSpecialCoordinatesImage_h
00019
00020 #include "itkSpecialCoordinatesImage.h"
00021 #include "itkImageRegion.h"
00022 #include "itkPoint.h"
00023 #include "itkContinuousIndex.h"
00024 #include "vnl/vnl_math.h"
00025
00026
00027 namespace itk
00028 {
00029
00085 template <class TPixel>
00086 class ITK_EXPORT PhasedArray3DSpecialCoordinatesImage :
00087 public SpecialCoordinatesImage<TPixel,3>
00088 {
00089 public:
00091 typedef PhasedArray3DSpecialCoordinatesImage Self;
00092 typedef SpecialCoordinatesImage<TPixel,3> Superclass;
00093 typedef SmartPointer<Self> Pointer;
00094 typedef SmartPointer<const Self> ConstPointer;
00095 typedef WeakPointer<const Self> ConstWeakPointer;
00096
00098 itkNewMacro(Self);
00099
00101 itkTypeMacro(PhasedArray3DSpecialCoordinatesImage, SpecialCoordinatesImage);
00102
00105 typedef TPixel PixelType;
00106
00108 typedef TPixel ValueType ;
00109
00114 typedef TPixel InternalPixelType;
00115
00118 typedef DefaultPixelAccessor< PixelType > AccessorType;
00119
00123 typedef DefaultPixelAccessorFunctor< Self > AccessorFunctorType;
00124
00129 itkStaticConstMacro(ImageDimension, unsigned int, 3);
00130
00132 typedef ImportImageContainer<unsigned long, PixelType> PixelContainer;
00133
00135 typedef typename Superclass::IndexType IndexType;
00136
00138 typedef typename Superclass::OffsetType OffsetType;
00139
00141 typedef typename Superclass::SizeType SizeType;
00142
00144 typedef typename Superclass::RegionType RegionType;
00145
00150 typedef typename Superclass::SpacingType SpacingType;
00151
00154 typedef typename Superclass::PointType PointType;
00155
00157 typedef typename PixelContainer::Pointer PixelContainerPointer;
00158 typedef typename PixelContainer::ConstPointer PixelContainerConstPointer;
00159
00164 template<class TCoordRep>
00165 bool TransformPhysicalPointToContinuousIndex(
00166 const Point<TCoordRep, 3>& point,
00167 ContinuousIndex<TCoordRep, 3>& index ) const
00168 {
00169 RegionType region = this->GetLargestPossibleRegion();
00170 double maxAzimuth = region.GetSize(0) - 1;
00171 double maxElevation = region.GetSize(1) - 1;
00172
00173
00174 TCoordRep azimuth = atan(point[0] / point[2]);
00175 TCoordRep elevation = atan(point[1] / point[2]);
00176 TCoordRep radius = sqrt( point[0] * point[0]
00177 + point[1] * point[1]
00178 + point[2] * point[2] );
00179
00180
00181 index[0] = static_cast<TCoordRep>( (azimuth/m_AzimuthAngularSeparation)
00182 + (maxAzimuth/2.0) );
00183 index[1] = static_cast<TCoordRep>( (elevation/m_ElevationAngularSeparation)
00184 + (maxElevation/2.0) );
00185 index[2] = static_cast<TCoordRep>( ( (radius-m_FirstSampleDistance)
00186 / m_RadiusSampleSize) );
00187
00188
00189 const bool isInside = region.IsInside( index );
00190
00191 return isInside;
00192 }
00193
00198 template<class TCoordRep>
00199 bool TransformPhysicalPointToIndex(
00200 const Point<TCoordRep, 3>& point,
00201 IndexType & index ) const
00202 {
00203 typedef typename IndexType::IndexValueType IndexValueType;
00204
00205 RegionType region = this->GetLargestPossibleRegion();
00206 double maxAzimuth = region.GetSize(0) - 1;
00207 double maxElevation = region.GetSize(1) - 1;
00208
00209
00210 TCoordRep azimuth = atan(point[0] / point[2]);
00211 TCoordRep elevation = atan(point[1] / point[2]);
00212 TCoordRep radius = sqrt( point[0] * point[0]
00213 + point[1] * point[1]
00214 + point[2] * point[2] );
00215
00216
00217 index[0] = static_cast<IndexValueType>( (azimuth/m_AzimuthAngularSeparation)
00218 + (maxAzimuth/2.0) );
00219 index[1] = static_cast<IndexValueType>( (elevation/m_ElevationAngularSeparation)
00220 + (maxElevation/2.0) );
00221 index[2] = static_cast<IndexValueType>( ( (radius-m_FirstSampleDistance)
00222 / m_RadiusSampleSize ) );
00223
00224
00225 const bool isInside = region.IsInside( index );
00226
00227 return isInside;
00228 }
00229
00234 template<class TCoordRep>
00235 void TransformContinuousIndexToPhysicalPoint(
00236 const ContinuousIndex<TCoordRep, 3>& index,
00237 Point<TCoordRep, 3>& point ) const
00238 {
00239 RegionType region = this->GetLargestPossibleRegion();
00240 double maxAzimuth = region.GetSize(0) - 1;
00241 double maxElevation = region.GetSize(1) - 1;
00242
00243
00244 TCoordRep azimuth = ( index[0] - (maxAzimuth/2.0) )
00245 * m_AzimuthAngularSeparation;
00246 TCoordRep elevation = ( index[1] - (maxElevation/2.0) )
00247 * m_ElevationAngularSeparation;
00248 TCoordRep radius = (index[2]*m_RadiusSampleSize)+m_FirstSampleDistance;
00249
00250
00251 TCoordRep tanOfAzimuth = tan(azimuth);
00252 TCoordRep tanOfElevation = tan(elevation);
00253 point[2] = static_cast<TCoordRep>( radius /
00254 sqrt(1 + tanOfAzimuth*tanOfAzimuth + tanOfElevation*tanOfElevation));
00255 point[1] = static_cast<TCoordRep>( point[2] * tanOfElevation );
00256 point[0] = static_cast<TCoordRep>( point[2] * tanOfAzimuth );
00257 }
00258
00264 template<class TCoordRep>
00265 void TransformIndexToPhysicalPoint(
00266 const IndexType & index,
00267 Point<TCoordRep, 3>& point ) const
00268 {
00269 RegionType region = this->GetLargestPossibleRegion();
00270 double maxAzimuth = region.GetSize(0) - 1;
00271 double maxElevation = region.GetSize(1) - 1;
00272
00273
00274 TCoordRep azimuth = ( static_cast<double>(index[0]) - (maxAzimuth/2.0) )
00275 * m_AzimuthAngularSeparation;
00276 TCoordRep elevation = ( static_cast<double>(index[1]) - (maxElevation/2.0) )
00277 * m_ElevationAngularSeparation;
00278 TCoordRep radius = (static_cast<double>(index[2]) * m_RadiusSampleSize)
00279 + m_FirstSampleDistance;
00280
00281
00282 TCoordRep tanOfAzimuth = tan(azimuth);
00283 TCoordRep tanOfElevation = tan(elevation);
00284 point[2] = static_cast<TCoordRep>( radius / sqrt(
00285 1.0 + tanOfAzimuth*tanOfAzimuth + tanOfElevation*tanOfElevation) );
00286 point[1] = static_cast<TCoordRep>( point[2] * tanOfElevation );
00287 point[0] = static_cast<TCoordRep>( point[2] * tanOfAzimuth );
00288 }
00289
00290
00292 itkSetMacro(AzimuthAngularSeparation, double);
00293
00295 itkSetMacro(ElevationAngularSeparation, double);
00296
00298 itkSetMacro(RadiusSampleSize, double);
00299
00301 itkSetMacro(FirstSampleDistance, double);
00302
00303 protected:
00304 PhasedArray3DSpecialCoordinatesImage()
00305 {
00306 m_RadiusSampleSize = 1;
00307 m_AzimuthAngularSeparation = 1 * (2.0*vnl_math::pi/360.0);
00308 m_ElevationAngularSeparation = 1 * (2.0*vnl_math::pi/360.0);
00309 m_FirstSampleDistance = 0;
00310 }
00311 virtual ~PhasedArray3DSpecialCoordinatesImage() {};
00312 void PrintSelf(std::ostream& os, Indent indent) const;
00313
00314 private:
00315 PhasedArray3DSpecialCoordinatesImage(const Self&);
00316 void operator=(const Self&);
00317
00318 double m_AzimuthAngularSeparation;
00319 double m_ElevationAngularSeparation;
00320 double m_RadiusSampleSize;
00321 double m_FirstSampleDistance;
00322
00323 };
00324 #ifdef ITK_EXPLICIT_INSTANTIATION
00325 extern template class PhasedArray3DSpecialCoordinatesImage<float >;
00326 extern template class PhasedArray3DSpecialCoordinatesImage<double >;
00327 extern template class PhasedArray3DSpecialCoordinatesImage<unsigned char >;
00328 extern template class PhasedArray3DSpecialCoordinatesImage<unsigned short>;
00329 extern template class PhasedArray3DSpecialCoordinatesImage<unsigned int >;
00330 extern template class PhasedArray3DSpecialCoordinatesImage<signed char >;
00331 extern template class PhasedArray3DSpecialCoordinatesImage<signed short >;
00332 extern template class PhasedArray3DSpecialCoordinatesImage<signed int >;
00333 #endif
00334 }
00335 #ifndef ITK_MANUAL_INSTANTIATION
00336 #include "itkPhasedArray3DSpecialCoordinatesImage.txx"
00337 #endif
00338
00339 #endif
00340