FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
path.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2006-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file path.cpp
10 * @brief Implementation of the Path class.
11 */
12
13#include "path.h"
14
15#include <algorithm>
16#include <cstddef>
17
18#include "coord.h"
19#include "core/logging.h"
20#include "geometry_ops.h"
21#include "path_utils.h"
22
23using logging::Level;
24
25namespace math
26{
27 void Path::addCoord(const Coord& coord) noexcept
28 {
29 auto comp = [](const Coord& a, const Coord& b) { return a.t < b.t; };
30
31 const auto iter = std::ranges::lower_bound(_coords, coord, comp);
32 _coords.insert(iter, coord);
33 _final = false;
34 }
35
37 {
38 if (!_final)
39 {
40 LOG(Level::FATAL, "Finalize not called before GetPosition");
41 throw PathException("Finalize not called before GetPosition");
42 }
43
44 Coord coord{};
45 switch (_type)
46 {
48 getPositionStatic(coord, _coords);
49 break;
51 getPositionLinear(t, coord, _coords);
52 break;
54 getPositionCubic(t, coord, _coords, _dd);
55 break;
56 }
57 return coord.pos;
58 }
59
61 {
62 if (!_final)
63 {
64 LOG(Level::FATAL, "Finalize not called before GetVelocity");
65 throw PathException("Finalize not called before GetVelocity");
66 }
67
68 if (_coords.empty())
69 {
70 return {0, 0, 0};
71 }
72
73 switch (_type)
74 {
76 return {0, 0, 0};
77
79 {
80 auto xrp = std::ranges::upper_bound(_coords, t, {}, &Coord::t);
81 auto idx = std::distance(_coords.begin(), xrp);
82
83 // Clamp to valid segments
84 if (idx <= 0)
85 idx = 1;
86 if (static_cast<std::size_t>(idx) >= _coords.size())
87 idx = static_cast<decltype(idx)>(_coords.size() - 1);
88
89 if (idx < 1 || static_cast<std::size_t>(idx) >= _coords.size())
90 return {0, 0, 0}; // Should not happen if size >= 1 and clamp works
91
92 const auto right_idx = static_cast<std::size_t>(idx);
93 const auto left_idx = right_idx - 1;
94
95 const auto& p1 = _coords[left_idx];
96 const auto& p2 = _coords[right_idx];
97 const RealType dt = p2.t - p1.t;
98
99 if (dt <= EPSILON)
100 return {0, 0, 0};
101
102 return (p2.pos - p1.pos) / dt;
103 }
104
106 {
107 auto xrp = std::ranges::upper_bound(_coords, t, {}, &Coord::t);
108 std::ptrdiff_t xri;
109 if (xrp == _coords.begin())
110 xri = 1;
111 else if (xrp == _coords.end())
112 xri = static_cast<std::ptrdiff_t>(_coords.size() - 1);
113 else
114 xri = std::distance(_coords.begin(), xrp);
115
116 if (xri < 1 || static_cast<std::size_t>(xri) >= _coords.size())
117 return {0, 0, 0};
118
119 const auto right_idx = static_cast<std::size_t>(xri);
120 const auto left_idx = right_idx - 1;
121
122 const RealType h = _coords[right_idx].t - _coords[left_idx].t;
123 if (h <= EPSILON)
124 return {0, 0, 0};
125
126 const RealType a = (_coords[right_idx].t - t) / h;
127 const RealType b = (t - _coords[left_idx].t) / h;
128
129 // Derivative coefficients
130 // da/dt = -1/h
131 // db/dt = 1/h
132 // dc/dt = -h/6 * (3a^2 - 1)
133 // dd/dt = h/6 * (3b^2 - 1)
134
135 const RealType da = -1.0 / h;
136 const RealType db = 1.0 / h;
137 const RealType dc = -h / 6.0 * (3.0 * a * a - 1.0);
138 const RealType dd_coeff = h / 6.0 * (3.0 * b * b - 1.0);
139
140 return _coords[left_idx].pos * da + _coords[right_idx].pos * db + _dd[left_idx].pos * dc +
141 _dd[right_idx].pos * dd_coeff;
142 }
143 }
144 return {0, 0, 0};
145 }
146
148 {
149 if (!_final)
150 {
151 switch (_type)
152 {
155 break;
157 finalizeCubic<Coord>(_coords, _dd);
158 break;
159 }
160 _final = true;
161 }
162 }
163
164 void Path::setInterp(const InterpType settype) noexcept
165 {
166 _type = settype;
167 _final = false;
168 }
169}
Exception class for handling path-related errors.
Definition path_utils.h:32
Vec3 getPosition(RealType t) const
Retrieves the position at a given time along the path.
Definition path.cpp:36
void setInterp(InterpType settype) noexcept
Changes the interpolation type.
Definition path.cpp:164
InterpType
Types of interpolation supported by the Path class.
Definition path.h:36
Vec3 getVelocity(RealType t) const
Retrieves the velocity at a given time along the path.
Definition path.cpp:60
void addCoord(const Coord &coord) noexcept
Adds a coordinate to the path.
Definition path.cpp:27
void finalize()
Finalizes the path, preparing it for interpolation.
Definition path.cpp:147
A class representing a vector in rectangular coordinates.
double RealType
Type for real numbers.
Definition config.h:27
constexpr RealType EPSILON
Machine epsilon for real numbers.
Definition config.h:51
Coordinate and rotation structure operations.
Classes and operations for 3D geometry.
Header file for the logging system.
#define LOG(level,...)
Definition logging.h:19
Definition coord.h:18
Provides the definition and functionality of the Path class for handling coordinate-based paths with ...
Utility functions for path interpolation and exception handling.
void getPositionLinear(RealType t, T &coord, const std::vector< T > &coords)
Performs linear interpolation between coordinate points.
Definition path_utils.h:90
void getPositionStatic(T &coord, const std::vector< T > &coords)
Interpolates a static position from a list of coordinates.
Definition path_utils.h:71
void getPositionCubic(RealType t, T &coord, const std::vector< T > &coords, const std::vector< T > &dd)
Performs cubic spline interpolation between coordinate points.
Definition path_utils.h:134
Represents a position in 3D space with an associated time.
Definition coord.h:24
RealType t
Time.
Definition coord.h:26