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 OffsetType offset, tempOffset, zeroOffset;
40 InPathInputType inPathInput;
41 int dimension = OffsetType::GetOffsetDimension();
46 inPathInput = inPath.StartOfInput();
47 chainPath.SetStart(inPath.EvaluateToIndex(inPathInput));
49 for (ChainInputType chainInput = 0;;)
51 offset = inPath.IncrementInput(inPathInput);
52 if (zeroOffset == offset)
57 if (!restrictMovement)
59 chainPath.InsertStep(chainInput++, offset);
63 for (
int d = 0; d < dimension; ++d)
66 tempOffset[d] = offset[d];
67 chainPath.InsertStep(chainInput++, tempOffset);
79 template <
typename TFourierSeriesPath,
typename TChainCodePath>
82 const TChainCodePath & chainPath,
83 unsigned int numHarmonics = 8)
86 using OffsetType =
typename TFourierSeriesPath::OffsetType;
90 using FSInputType =
typename TFourierSeriesPath::InputType;
91 using ChainInputType =
typename TChainCodePath::InputType;
98 int dimension = OffsetType::GetOffsetDimension();
99 size_t numSteps = chainPath.NumberOfSteps();
101 const double PI = 4.0 * std::atan(1.0);
106 if (numHarmonics <= 1)
110 else if (numHarmonics * 2 > numSteps)
112 numHarmonics = numSteps / 2;
115 for (
unsigned int n = 0; n < numHarmonics; ++n)
117 index = chainPath.GetStart();
118 cosCoefficient.Fill(0.0);
119 sinCoefficient.Fill(0.0);
121 for (ChainInputType step = 0; step < numSteps; ++step)
123 index += chainPath.Evaluate(step);
124 theta = 2 * n * PI * (static_cast<double>(step + 1)) / numSteps;
127 for (
int d = 0; d < dimension; ++d)
129 indexVector[d] = index[d];
131 cosCoefficient += indexVector * (std::cos(theta) / numSteps);
132 sinCoefficient += indexVector * (std::sin(theta) / numSteps);
135 FSPath.AddHarmonic(cosCoefficient, sinCoefficient);