18 #ifndef itkPathFunctions_h
19 #define itkPathFunctions_h
31 template <
typename TChainCodePath,
typename TPathInput>
35 using OffsetType =
typename TChainCodePath::OffsetType;
36 using ChainInputType =
typename TChainCodePath::InputType;
37 using InPathInputType =
typename TPathInput::InputType;
39 const int dimension = OffsetType::GetOffsetDimension();
41 constexpr OffsetType zeroOffset{};
44 InPathInputType inPathInput = inPath.StartOfInput();
45 chainPath.SetStart(inPath.EvaluateToIndex(inPathInput));
47 for (ChainInputType chainInput = 0;;)
49 OffsetType offset = inPath.IncrementInput(inPathInput);
50 if (zeroOffset == offset)
55 if (!restrictMovement)
57 chainPath.InsertStep(chainInput++, offset);
61 for (
int d = 0; d < dimension; ++d)
63 OffsetType tempOffset{};
64 tempOffset[d] = offset[d];
65 chainPath.InsertStep(chainInput++, tempOffset);
77 template <
typename TFourierSeriesPath,
typename TChainCodePath>
80 const TChainCodePath & chainPath,
81 unsigned int numHarmonics = 8)
84 using OffsetType =
typename TFourierSeriesPath::OffsetType;
88 using FSInputType =
typename TFourierSeriesPath::InputType;
89 using ChainInputType =
typename TChainCodePath::InputType;
91 const int dimension = OffsetType::GetOffsetDimension();
92 const size_t numSteps = chainPath.NumberOfSteps();
94 const double PI = 4.0 * std::atan(1.0);
99 if (numHarmonics <= 1)
103 else if (numHarmonics * 2 > numSteps)
105 numHarmonics = numSteps / 2;
108 for (
unsigned int n = 0; n < numHarmonics; ++n)
114 for (ChainInputType step = 0; step < numSteps; ++step)
116 index += chainPath.Evaluate(step);
117 const FSInputType theta = 2 * n * PI * (static_cast<double>(step + 1)) / numSteps;
121 for (
int d = 0; d < dimension; ++d)
123 indexVector[d] = index[d];
125 cosCoefficient += indexVector * (std::cos(theta) / numSteps);
126 sinCoefficient += indexVector * (std::sin(theta) / numSteps);
129 FSPath.AddHarmonic(cosCoefficient, sinCoefficient);