ITK  5.4.0
Insight Toolkit
itkPhasedArray3DSpecialCoordinatesImage.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkPhasedArray3DSpecialCoordinatesImage_h
19#define itkPhasedArray3DSpecialCoordinatesImage_h
20
22#include "itkPoint.h"
23#include "itkMath.h"
26
27namespace itk
28{
94template <typename TPixel>
95class ITK_TEMPLATE_EXPORT PhasedArray3DSpecialCoordinatesImage : public SpecialCoordinatesImage<TPixel, 3>
96{
97public:
98 ITK_DISALLOW_COPY_AND_MOVE(PhasedArray3DSpecialCoordinatesImage);
99
106
108 itkNewMacro(Self);
109
111 itkOverrideGetNameOfClassMacro(PhasedArray3DSpecialCoordinatesImage);
112
115 using PixelType = TPixel;
116
118 using ValueType = TPixel;
119
124 using InternalPixelType = TPixel;
125
126 using typename Superclass::IOPixelType;
127
131
136
140
145 static constexpr unsigned int ImageDimension = 3;
146
148 using typename Superclass::IndexType;
149 using typename Superclass::IndexValueType;
150
152 using typename Superclass::OffsetType;
153
155 using typename Superclass::SizeType;
156 using typename Superclass::SizeValueType;
157
160
164 using typename Superclass::RegionType;
165
172 using typename Superclass::SpacingType;
173
178 using typename Superclass::PointType;
179
183
185 template <typename TIndexRep, typename TCoordRep>
188 {
189 const RegionType region = this->GetLargestPossibleRegion();
190 const double maxAzimuth = region.GetSize(0) - 1;
191 const double maxElevation = region.GetSize(1) - 1;
194 // Convert Cartesian coordinates into angular coordinates
195 TCoordRep azimuth = Math::pi_over_2;
196 TCoordRep elevation = Math::pi_over_2;
197 if (point[2] != 0.0)
198 {
199 azimuth = std::atan(point[0] / point[2]);
200 elevation = std::atan(point[1] / point[2]);
201 }
202 const TCoordRep radius = std::sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
203
204 // Convert the "proper" angular coordinates into index format
206 index[0] = static_cast<TCoordRep>((azimuth / m_AzimuthAngularSeparation) + (maxAzimuth / 2.0));
207 index[1] = static_cast<TCoordRep>((elevation / m_ElevationAngularSeparation) + (maxElevation / 2.0));
208 index[2] = static_cast<TCoordRep>(((radius - m_FirstSampleDistance) / m_RadiusSampleSize));
209 return index;
210 }
211
220 template <typename TCoordRep, typename TIndexRep>
221 ITK_NODISCARD("Call the overload which has the point as the only parameter and returns the index")
222 bool TransformPhysicalPointToContinuousIndex(const Point<TCoordRep, 3> & point,
223 ContinuousIndex<TIndexRep, 3> & index) const
224 {
225 index = this->TransformPhysicalPointToContinuousIndex<TIndexRep>(point);
226
227 // Now, check to see if the index is within allowed bounds
228 const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
229
230 return isInside;
231 }
232
236 template <typename TCoordRep>
237 [[nodiscard]] IndexType
239 {
240 const RegionType region = this->GetLargestPossibleRegion();
241 const double maxAzimuth = region.GetSize(0) - 1;
242 const double maxElevation = region.GetSize(1) - 1;
245 // Convert Cartesian coordinates into angular coordinates
246 TCoordRep azimuth = Math::pi_over_2;
247 TCoordRep elevation = Math::pi_over_2;
248 if (point[2] != 0.0)
249 {
250 azimuth = std::atan(point[0] / point[2]);
251 elevation = std::atan(point[1] / point[2]);
252 }
253 const TCoordRep radius = std::sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
254
255 // Convert the "proper" angular coordinates into index format
256 IndexType index;
257 index[0] = static_cast<IndexValueType>((azimuth / m_AzimuthAngularSeparation) + (maxAzimuth / 2.0));
258 index[1] = static_cast<IndexValueType>((elevation / m_ElevationAngularSeparation) + (maxElevation / 2.0));
259 index[2] = static_cast<IndexValueType>(((radius - m_FirstSampleDistance) / m_RadiusSampleSize));
260 return index;
261 }
262
271 template <typename TCoordRep>
272 ITK_NODISCARD("Call the overload which has the point as the only parameter and returns the index")
273 bool TransformPhysicalPointToIndex(const Point<TCoordRep, 3> & point, IndexType & index) const
274 {
275 index = this->TransformPhysicalPointToIndex(point);
276
277 // Now, check to see if the index is within allowed bounds
278 const bool isInside = this->GetLargestPossibleRegion().IsInside(index);
279
280 return isInside;
281 }
282
287 template <typename TCoordRep, typename TIndexRep>
288 void
291 {
292 const RegionType region = this->GetLargestPossibleRegion();
293 const double maxAzimuth = region.GetSize(0) - 1;
294 const double maxElevation = region.GetSize(1) - 1;
297 // Convert the index into proper angular coordinates
298 const TCoordRep azimuth = (index[0] - (maxAzimuth / 2.0)) * m_AzimuthAngularSeparation;
299 const TCoordRep elevation = (index[1] - (maxElevation / 2.0)) * m_ElevationAngularSeparation;
300 const TCoordRep radius = (index[2] * m_RadiusSampleSize) + m_FirstSampleDistance;
301
302 // Convert the angular coordinates into Cartesian coordinates
303 const TCoordRep tanOfAzimuth = std::tan(azimuth);
304 const TCoordRep tanOfElevation = std::tan(elevation);
305
306 point[2] =
307 static_cast<TCoordRep>(radius / std::sqrt(1 + tanOfAzimuth * tanOfAzimuth + tanOfElevation * tanOfElevation));
308 point[1] = static_cast<TCoordRep>(point[2] * tanOfElevation);
309 point[0] = static_cast<TCoordRep>(point[2] * tanOfAzimuth);
310 }
311
313 template <typename TCoordRep, typename TIndexRep>
314 [[nodiscard]] Point<TCoordRep, 3>
316 {
318 this->TransformContinuousIndexToPhysicalPoint(index, point);
319 return point;
320 }
328 template <typename TCoordRep>
329 void
331 {
332 const RegionType region = this->GetLargestPossibleRegion();
333 const double maxAzimuth = region.GetSize(0) - 1;
334 const double maxElevation = region.GetSize(1) - 1;
337 // Convert the index into proper angular coordinates
338 const TCoordRep azimuth = (static_cast<double>(index[0]) - (maxAzimuth / 2.0)) * m_AzimuthAngularSeparation;
339 const TCoordRep elevation = (static_cast<double>(index[1]) - (maxElevation / 2.0)) * m_ElevationAngularSeparation;
340 const TCoordRep radius = (static_cast<double>(index[2]) * m_RadiusSampleSize) + m_FirstSampleDistance;
341
342 // Convert the angular coordinates into Cartesian coordinates
343 const TCoordRep tanOfAzimuth = std::tan(azimuth);
344 const TCoordRep tanOfElevation = std::tan(elevation);
345
346 point[2] =
347 static_cast<TCoordRep>(radius / std::sqrt(1.0 + tanOfAzimuth * tanOfAzimuth + tanOfElevation * tanOfElevation));
348 point[1] = static_cast<TCoordRep>(point[2] * tanOfElevation);
349 point[0] = static_cast<TCoordRep>(point[2] * tanOfAzimuth);
350 }
351
353 template <typename TCoordRep>
354 [[nodiscard]] Point<TCoordRep, 3>
356 {
358 this->TransformIndexToPhysicalPoint(index, point);
359 return point;
360 }
364 itkSetMacro(AzimuthAngularSeparation, double);
365
367 itkSetMacro(ElevationAngularSeparation, double);
368
370 itkSetMacro(RadiusSampleSize, double);
371
373 itkSetMacro(FirstSampleDistance, double);
374
375 template <typename TCoordRep>
377 {}
378
379 template <typename TCoordRep>
380 void
382 {}
383
385 AccessorType
387 {
388 return AccessorType();
389 }
390
392 const AccessorType
394 {
395 return AccessorType();
396 }
397
399 NeighborhoodAccessorFunctorType
401 {
403 }
404
406 const NeighborhoodAccessorFunctorType
408 {
410 }
411
412protected:
414 {
415 m_RadiusSampleSize = 1;
416 m_AzimuthAngularSeparation = 1 * (2.0 * itk::Math::pi / 360.0); // 1
417 // degree
418 m_ElevationAngularSeparation = 1 * (2.0 * itk::Math::pi / 360.0); // 1
419 // degree
420 m_FirstSampleDistance = 0;
421 }
422
424 void
425 PrintSelf(std::ostream & os, Indent indent) const override;
426
427private:
428 double m_AzimuthAngularSeparation{}; // in radians
429 double m_ElevationAngularSeparation{}; // in radians
430 double m_RadiusSampleSize{};
431 double m_FirstSampleDistance{};
432};
433} // end namespace itk
434
435#ifndef ITK_MANUAL_INSTANTIATION
436# include "itkPhasedArray3DSpecialCoordinatesImage.hxx"
437#endif
438
439#endif
A templated class holding a point in n-Dimensional image space.
Base class for all data objects in ITK.
Provides a common API for pixel accessors for Image and VectorImage.
Give access to partial aspects a type.
typename IndexType::IndexValueType IndexValueType
Definition: itkImageBase.h:142
An image region represents a structured region of data.
const SizeType & GetSize() const
Defines an itk::Image front-end to a standard C-array.
Control indentation during Print() invocation.
Definition: itkIndent.h:50
Provides accessor interfaces to Get pixels and is meant to be used on pointers contained within Neigh...
Base class for most ITK classes.
Definition: itkObject.h:62
Templated 3D nonrectilinear-coordinate image class for phased-array "range" images.
typename PixelContainer::ConstPointer PixelContainerConstPointer
IndexType TransformPhysicalPointToIndex(const Point< TCoordRep, 3 > &point) const
const NeighborhoodAccessorFunctorType GetNeighborhoodAccessor() const
~PhasedArray3DSpecialCoordinatesImage() override=default
void TransformPhysicalVectorToLocalVector(const FixedArray< TCoordRep, 3 > &, FixedArray< TCoordRep, 3 > &) const
void TransformLocalVectorToPhysicalVector(FixedArray< TCoordRep, 3 > &) const
void TransformContinuousIndexToPhysicalPoint(const ContinuousIndex< TIndexRep, 3 > &index, Point< TCoordRep, 3 > &point) const
void TransformIndexToPhysicalPoint(const IndexType &index, Point< TCoordRep, 3 > &point) const
ContinuousIndex< TIndexRep, 3 > TransformPhysicalPointToContinuousIndex(const Point< TCoordRep, 3 > &point) const
Point< TCoordRep, 3 > TransformIndexToPhysicalPoint(const IndexType &index) const
void PrintSelf(std::ostream &os, Indent indent) const override
Point< TCoordRep, 3 > TransformContinuousIndexToPhysicalPoint(const ContinuousIndex< TIndexRep, 3 > &index) const
A templated class holding a geometric point in n-Dimensional space.
Definition: itkPoint.h:54
Templated n-dimensional nonrectilinear-coordinate image base class.
Implements a weak reference to an object.
SmartPointer< const Self > ConstPointer
SmartPointer< Self > Pointer
static constexpr double pi_over_2
Definition: itkMath.h:70
static constexpr double pi
Definition: itkMath.h:66
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
*par Constraints *The filter image with at least two dimensions and a vector *length of at least The theory supports extension to scalar but *the implementation of the itk vector classes do not **The template parameter TRealType must be floating point(float or double) or *a user-defined "real" numerical type with arithmetic operations defined *sufficient to compute derivatives. **\par Performance *This filter will automatically multithread if run with *SetUsePrincipleComponents
long IndexValueType
Definition: itkIntTypes.h:90
unsigned long SizeValueType
Definition: itkIntTypes.h:83