diff --git a/include/itkCartesianToPolarTransform.h b/include/itkCartesianToPolarTransform.h index 15be674..069b3e3 100644 --- a/include/itkCartesianToPolarTransform.h +++ b/include/itkCartesianToPolarTransform.h @@ -155,6 +155,21 @@ class ITK_TEMPLATE_EXPORT CartesianToPolarTransform : itkSetMacro( Center, InputPointType ); itkGetConstReferenceMacro( Center, InputPointType ); + /** Set an angular offset for the polar coordinate transform. + * + * Defaults to 0.0 + */ + itkSetMacro( AngleOffset, typename OutputPointType::ValueType ); + itkGetConstReferenceMacro( AngleOffset, typename OutputPointType::ValueType ); + + /** Enable/Disable to use constant arc increment instead of constant angular increment. + * + * Defaults to Off + */ + itkSetMacro(ConstArcIncr, bool); + itkGetMacro(ConstArcIncr, bool); + itkBooleanMacro(ConstArcIncr); + protected: CartesianToPolarTransform(); ~CartesianToPolarTransform() override; @@ -164,6 +179,8 @@ class ITK_TEMPLATE_EXPORT CartesianToPolarTransform : private: InputPointType m_Center; + typename OutputPointType::ValueType m_AngleOffset = 0; + bool m_ConstArcIncr = false; }; //class CartesianToPolarTransform } // namespace itk diff --git a/include/itkCartesianToPolarTransform.hxx b/include/itkCartesianToPolarTransform.hxx index a579bb3..f10337f 100644 --- a/include/itkCartesianToPolarTransform.hxx +++ b/include/itkCartesianToPolarTransform.hxx @@ -59,13 +59,19 @@ CartesianToPolarTransform const InputPointType vector = inputPoint - this->m_Center; - outputPoint[1] = std::sqrt( vector[0] * vector[0] + vector[1] * vector[1] ); - outputPoint[0] = std::acos( vector[0] / outputPoint[1] ); + outputPoint[1] = std::sqrt( vector[0] * vector[0] + vector[1] * vector[1] ); // r= sqrt(x^2 + y^2) + outputPoint[0] = std::acos( vector[0] / outputPoint[1] ); // alpha = acos(x/r) + outputPoint[0] += m_AngleOffset; // add offset before 2*pi adjustment to keep values within [-pi,pi] if( vector[1] < 0.0 ) { outputPoint[0] = Math::twopi - outputPoint[0]; } + if(m_ConstArcIncr) + { + outputPoint[0] *= outputPoint[1]; // arc= r*alpha + } + return outputPoint; } diff --git a/include/itkPolarToCartesianTransform.h b/include/itkPolarToCartesianTransform.h index 8d7d123..001030e 100644 --- a/include/itkPolarToCartesianTransform.h +++ b/include/itkPolarToCartesianTransform.h @@ -152,6 +152,29 @@ class ITK_TEMPLATE_EXPORT PolarToCartesianTransform: itkSetMacro( Center, OutputPointType ); itkGetConstReferenceMacro( Center, OutputPointType ); + /** Set an angular offset for the polar coordinate transform. + * + * Defaults to 0.0 + */ + itkSetMacro( AngleOffset, typename InputPointType::ValueType ); + itkGetConstReferenceMacro( AngleOffset, typename InputPointType::ValueType ); + + /** Enable/Disable to use constant arc increment instead of constant angular increment. + * + * Defaults to Off + */ + itkSetMacro(ConstArcIncr, bool); + itkGetMacro(ConstArcIncr, bool); + itkBooleanMacro(ConstArcIncr); + + /** Enable/Disable to return NaN in case alpha is outside [-pi,pi]. + * + * Defaults to Off + */ + itkSetMacro(ReturnNaN, bool); + itkGetMacro(ReturnNaN, bool); + itkBooleanMacro(ReturnNaN); + protected: PolarToCartesianTransform(); ~PolarToCartesianTransform() override; @@ -161,6 +184,9 @@ class ITK_TEMPLATE_EXPORT PolarToCartesianTransform: private: OutputPointType m_Center; + typename InputPointType::ValueType m_AngleOffset = 0; + bool m_ConstArcIncr = false; + bool m_ReturnNaN = false; }; //class PolarToCartesianTransform } // namespace itk diff --git a/include/itkPolarToCartesianTransform.hxx b/include/itkPolarToCartesianTransform.hxx index faa64e9..48472de 100644 --- a/include/itkPolarToCartesianTransform.hxx +++ b/include/itkPolarToCartesianTransform.hxx @@ -56,8 +56,24 @@ PolarToCartesianTransform { OutputPointType outputPoint(inputPoint); - outputPoint[0] = inputPoint[1] * std::cos(inputPoint[0]); //r*cos(alpha) - outputPoint[1] = inputPoint[1] * std::sin(inputPoint[0]); //r*sin(alpha) + double alpha = inputPoint[0]; + if(m_ConstArcIncr) + { + alpha /= inputPoint[1]; // alpha = arc/r + } + + if(m_ReturnNaN && (alpha < -Math::pi || Math::pi < alpha)) + { + using PointNumericTraits = NumericTraits; + outputPoint[0] = PointNumericTraits::quiet_NaN(); + outputPoint[1] = PointNumericTraits::quiet_NaN(); + return outputPoint; + } + + alpha += m_AngleOffset; // add offset after NaN return to keep values within [-pi,pi] + + outputPoint[0] = inputPoint[1] * std::cos(alpha); //r*cos(alpha) + outputPoint[1] = inputPoint[1] * std::sin(alpha); //r*sin(alpha) for( unsigned int ii = 0; ii < SpaceDimension; ++ii ) {