FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
path_utils.h File Reference

Utility functions for path interpolation and exception handling. More...

#include <algorithm>
#include <concepts>
#include <stdexcept>
#include <vector>
#include "core/config.h"
+ Include dependency graph for path_utils.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  math::PathException
 Exception class for handling path-related errors. More...
 

Namespaces

namespace  math
 

Concepts

concept  Interpolatable
 Concept for types that can be interpolated.
 

Functions

template<Interpolatable T>
void getPositionStatic (T &coord, const std::vector< T > &coords)
 Interpolates a static position from a list of coordinates.
 
template<Interpolatable T>
void getPositionLinear (RealType t, T &coord, const std::vector< T > &coords)
 Performs linear interpolation between coordinate points.
 
template<Interpolatable T>
void getPositionCubic (RealType t, T &coord, const std::vector< T > &coords, const std::vector< T > &dd)
 Performs cubic spline interpolation between coordinate points.
 
template<Interpolatable T>
void finalizeCubic (const std::vector< T > &coords, std::vector< T > &dd)
 Finalizes cubic spline interpolation by calculating second derivatives.
 

Detailed Description

Utility functions for path interpolation and exception handling.

The cubic interpolation functions are based on methods described in "Numerical Recipes in C, Second Edition" by Press et al., but the code here is distinct from the original.

Definition in file path_utils.h.

Function Documentation

◆ finalizeCubic()

template<Interpolatable T>
void finalizeCubic ( const std::vector< T > &  coords,
std::vector< T > &  dd 
)

Finalizes cubic spline interpolation by calculating second derivatives.

Template Parameters
TThe type of the coordinate, which must satisfy the Interpolatable concept.
Parameters
coordsA vector of coordinates for which second derivatives will be calculated.
ddThe output vector that will store the calculated second derivatives.
Exceptions
PathExceptionif there are fewer than two points for interpolation.

Definition at line 180 of file path_utils.h.

181{
182 using index_type = typename std::vector<T>::size_type;
183 const index_type size = coords.size();
184 if (size < 2)
185 {
186 throw math::PathException("Not enough points for cubic interpolation");
187 }
188
189 std::vector<T> tmp(size);
190 dd.resize(size);
191
192 dd.front() = 0;
193 dd.back() = 0;
194
195 for (index_type i = 1; i + 1 < size; ++i)
196 {
197 const index_type next_index = i + 1;
198 const index_type prev_index = i - 1;
199
200 const T yrd = coords[next_index] - coords[i];
201 const T yld = coords[i] - coords[prev_index];
202 const RealType xrd = coords[next_index].t - coords[i].t;
203 const RealType xld = coords[i].t - coords[prev_index].t;
204 const RealType iw = coords[next_index].t - coords[prev_index].t;
205
206 if (iw <= EPSILON)
207 {
208 dd[i] = 0.0;
209 tmp[i] = 0.0;
210 continue;
211 }
212
213 const T yrd_xrd = (xrd <= EPSILON) ? (yrd * 0.0) : (yrd / xrd);
214 const T yld_xld = (xld <= EPSILON) ? (yld * 0.0) : (yld / xld);
215
216 const RealType si = xld / iw;
217 const T p = dd[prev_index] * si + 2.0;
218 dd[i] = (si - 1.0) / p;
219 tmp[i] = ((yrd_xrd - yld_xld) * 6.0 / iw - tmp[prev_index] * si) / p;
220 }
221
222 for (index_type i = size - 1; i-- > 0;)
223 {
224 dd[i] = dd[i] * dd[i + 1] + tmp[i];
225 }
226}
Exception class for handling path-related errors.
Definition path_utils.h:32
double RealType
Type for real numbers.
Definition config.h:27
constexpr RealType EPSILON
Machine epsilon for real numbers.
Definition config.h:51

References EPSILON.

Referenced by math::RotationPath::finalize().

+ Here is the caller graph for this function:

◆ getPositionCubic()

template<Interpolatable T>
void getPositionCubic ( RealType  t,
T &  coord,
const std::vector< T > &  coords,
const std::vector< T > &  dd 
)

Performs cubic spline interpolation between coordinate points.

The method used for calculating the spline is from "Numerical Recipes in C."

Template Parameters
TThe type of the coordinate, which must satisfy the Interpolatable concept.
Parameters
tThe interpolation factor (usually time) to determine the position.
coordThe output coordinate that will be interpolated.
coordsA vector of coordinates to interpolate between.
ddA vector of second derivatives used in the cubic interpolation.
Exceptions
PathExceptionif the list of coordinates is empty.

Definition at line 134 of file path_utils.h.

135{
136 if (coords.empty())
137 {
138 throw math::PathException("coord list empty during GetPositionCubic");
139 }
140
141 auto xrp = std::ranges::upper_bound(coords, t, {}, &T::t);
142
143 if (xrp == coords.begin())
144 {
145 coord = *xrp;
146 }
147 else if (xrp == coords.end())
148 {
149 coord = *(xrp - 1);
150 }
151 else
152 {
153 using index_type = typename std::vector<T>::size_type;
154 const auto right_index = static_cast<index_type>(xrp - coords.begin());
155 const auto left_index = right_index - 1;
156
157 const RealType xrd = coords[right_index].t - t;
158 const RealType xld = t - coords[left_index].t;
159 const RealType iw = coords[right_index].t - coords[left_index].t;
160 const RealType iws = iw * iw / 6.0;
161 const RealType a = xrd / iw;
162 const RealType b = xld / iw;
163 const RealType c = (a * a * a - a) * iws;
164 const RealType d = (b * b * b - b) * iws;
165
166 coord = coords[left_index] * a + coords[right_index] * b + dd[left_index] * c + dd[right_index] * d;
167 }
168 coord.t = t;
169}
RealType c() noexcept
Get the speed of light.
Definition parameters.h:91

Referenced by math::Path::getPosition(), and math::RotationPath::getPosition().

+ Here is the caller graph for this function:

◆ getPositionLinear()

template<Interpolatable T>
void getPositionLinear ( RealType  t,
T &  coord,
const std::vector< T > &  coords 
)

Performs linear interpolation between coordinate points.

Template Parameters
TThe type of the coordinate, which must satisfy the Interpolatable concept.
Parameters
tThe interpolation factor (usually time) to determine the position.
coordThe output coordinate that will be interpolated.
coordsA vector of coordinates to interpolate between.
Exceptions
PathExceptionif the list of coordinates is empty.

Definition at line 90 of file path_utils.h.

91{
92 if (coords.empty())
93 {
94 throw math::PathException("coord list empty during GetPositionLinear");
95 }
96
97 auto xrp = std::ranges::upper_bound(coords, t, {}, &T::t);
98
99 if (xrp == coords.begin())
100 {
101 coord = *xrp;
102 }
103 else if (xrp == coords.end())
104 {
105 coord = *(xrp - 1);
106 }
107 else
108 {
109 using index_type = typename std::vector<T>::size_type;
110 const auto right_index = static_cast<index_type>(xrp - coords.begin());
111 const auto left_index = right_index - 1;
112
113 const RealType iw = coords[right_index].t - coords[left_index].t;
114 const RealType rw = (coords[right_index].t - t) / iw;
115 const RealType lw = 1 - rw;
116
117 coord = coords[right_index] * lw + coords[left_index] * rw;
118 }
119 coord.t = t;
120}

Referenced by math::Path::getPosition(), and math::RotationPath::getPosition().

+ Here is the caller graph for this function:

◆ getPositionStatic()

template<Interpolatable T>
void getPositionStatic ( T &  coord,
const std::vector< T > &  coords 
)

Interpolates a static position from a list of coordinates.

Template Parameters
TThe type of the coordinate, which must satisfy the Interpolatable concept.
Parameters
coordThe output coordinate to be set.
coordsA vector of coordinates from which the first will be selected.
Exceptions
PathExceptionif the list of coordinates is empty.

Definition at line 71 of file path_utils.h.

72{
73 if (coords.empty())
74 {
75 throw math::PathException("coord list empty during GetPositionStatic");
76 }
77 coord = coords[0];
78}

Referenced by math::Path::getPosition(), and math::RotationPath::getPosition().

+ Here is the caller graph for this function: