1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageEuclideanToPolar.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkImageEuclideanToPolar.h"
16
17 #include "vtkImageData.h"
18 #include "vtkImageProgressIterator.h"
19 #include "vtkMath.h"
20 #include "vtkObjectFactory.h"
21
22 #include <cmath>
23
24 vtkStandardNewMacro(vtkImageEuclideanToPolar);
25
26 //------------------------------------------------------------------------------
vtkImageEuclideanToPolar()27 vtkImageEuclideanToPolar::vtkImageEuclideanToPolar()
28 {
29 this->SetNumberOfInputPorts(1);
30 this->SetNumberOfOutputPorts(1);
31 this->ThetaMaximum = 255.0;
32 }
33
34 //------------------------------------------------------------------------------
35 // This templated function executes the filter for any type of data.
36 template <class T>
vtkImageEuclideanToPolarExecute(vtkImageEuclideanToPolar * self,vtkImageData * inData,vtkImageData * outData,int outExt[6],int id,T *)37 void vtkImageEuclideanToPolarExecute(vtkImageEuclideanToPolar* self, vtkImageData* inData,
38 vtkImageData* outData, int outExt[6], int id, T*)
39 {
40 vtkImageIterator<T> inIt(inData, outExt);
41 vtkImageProgressIterator<T> outIt(outData, outExt, self, id);
42 double X, Y, Theta, R;
43 double thetaMax = self->GetThetaMaximum();
44
45 // find the region to loop over
46 int maxC = inData->GetNumberOfScalarComponents();
47
48 // Loop through output pixels
49 while (!outIt.IsAtEnd())
50 {
51 T* inSI = inIt.BeginSpan();
52 T* outSI = outIt.BeginSpan();
53 T* outSIEnd = outIt.EndSpan();
54 while (outSI != outSIEnd)
55 {
56 // Pixel operation
57 X = static_cast<double>(*inSI);
58 Y = static_cast<double>(inSI[1]);
59
60 if ((X == 0.0) && (Y == 0.0))
61 {
62 Theta = 0.0;
63 R = 0.0;
64 }
65 else
66 {
67 Theta = atan2(Y, X) * thetaMax / (2.0 * vtkMath::Pi());
68 if (Theta < 0.0)
69 {
70 Theta += thetaMax;
71 }
72 R = sqrt(X * X + Y * Y);
73 }
74
75 *outSI = static_cast<T>(Theta);
76 outSI[1] = static_cast<T>(R);
77 inSI += maxC;
78 outSI += maxC;
79 }
80 inIt.NextSpan();
81 outIt.NextSpan();
82 }
83 }
84
85 //------------------------------------------------------------------------------
ThreadedExecute(vtkImageData * inData,vtkImageData * outData,int outExt[6],int id)86 void vtkImageEuclideanToPolar::ThreadedExecute(
87 vtkImageData* inData, vtkImageData* outData, int outExt[6], int id)
88 {
89 vtkDebugMacro(<< "Execute: inData = " << inData << ", outData = " << outData);
90
91 // this filter expects that input is the same type as output.
92 if (inData->GetScalarType() != outData->GetScalarType())
93 {
94 vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
95 << ", must match out ScalarType " << outData->GetScalarType());
96 return;
97 }
98
99 // input must have at least two components
100 if (inData->GetNumberOfScalarComponents() < 2)
101 {
102 vtkErrorMacro(<< "Execute: input does not have at least two components");
103 return;
104 }
105
106 switch (inData->GetScalarType())
107 {
108 vtkTemplateMacro(vtkImageEuclideanToPolarExecute(
109 this, inData, outData, outExt, id, static_cast<VTK_TT*>(nullptr)));
110 default:
111 vtkErrorMacro(<< "Execute: Unknown ScalarType");
112 return;
113 }
114 }
115
PrintSelf(ostream & os,vtkIndent indent)116 void vtkImageEuclideanToPolar::PrintSelf(ostream& os, vtkIndent indent)
117 {
118 this->Superclass::PrintSelf(os, indent);
119
120 os << indent << "Maximum Angle: " << this->ThetaMaximum << "\n";
121 }
122