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);
80 const TChainCodePath & chainPath,
81 unsigned int numHarmonics = 8)
83 using IndexType =
typename TFourierSeriesPath::IndexType;
84 using OffsetType =
typename TFourierSeriesPath::OffsetType;
85 using VectorType =
typename TFourierSeriesPath::VectorType;
87 using FSInputType =
typename TFourierSeriesPath::InputType;
88 using ChainInputType =
typename TChainCodePath::InputType;
90 const int dimension = OffsetType::GetOffsetDimension();
91 const size_t numSteps = chainPath.NumberOfSteps();
93 const double PI = 4.0 * std::atan(1.0);
98 if (numHarmonics <= 1)
102 else if (numHarmonics * 2 > numSteps)
104 numHarmonics = numSteps / 2;
107 for (
unsigned int n = 0; n < numHarmonics; ++n)
109 IndexType index = chainPath.GetStart();
110 VectorType cosCoefficient{};
111 VectorType sinCoefficient{};
113 for (ChainInputType step = 0; step < numSteps; ++step)
115 index += chainPath.Evaluate(step);
116 const FSInputType theta = 2 * n * PI * (
static_cast<double>(step + 1)) / numSteps;
119 VectorType indexVector;
120 for (
int d = 0; d < dimension; ++d)
122 indexVector[d] = index[d];
124 cosCoefficient += indexVector * (std::cos(theta) / numSteps);
125 sinCoefficient += indexVector * (std::sin(theta) / numSteps);
128 FSPath.AddHarmonic(cosCoefficient, sinCoefficient);