8#include "core/math/spline/cubic_hermite_spline.h"
9#include "core/math/spline/quintic_hermite_spline.h"
33 const std::vector<HermitePoint>& points,
36 double max_err = 1e-4) {
38 if (points.size() < 2 || !factory) {
42 path.segments_.reserve(points.size() - 1);
43 path.segment_starts_.reserve(points.size() - 1);
46 for (
size_t i = 0; i + 1 < points.size(); ++i) {
47 std::unique_ptr<SplineBase> segment = factory(points[i], points[i + 1], max_err);
48 if (!segment)
continue;
50 path.segment_starts_.push_back(accum);
51 accum += segment->length();
52 path.segments_.push_back(std::move(segment));
54 path.total_length_ = accum;
71 double max_err) -> std::unique_ptr<SplineBase> {
82 bool empty()
const {
return segments_.empty(); }
88 double length()
const {
return total_length_; }
97 if (segments_.empty()) {
105 if (s >= total_length_) {
106 SplineSample out = segments_.back()->sample_by_s(segments_.back()->length());
107 out.
s = total_length_;
111 const size_t idx = segment_index_for_s(s);
112 const double local_s = s - segment_starts_[idx];
113 SplineSample out = segments_[idx]->sample_by_s(local_s);
124 std::vector<Translation2d> points;
125 if (segments_.empty() || ds <= 0.0) {
128 for (
double s = 0.0; s < total_length_; s += ds) {
131 points.push_back(
sample_by_s(total_length_).position);
141 std::vector<Translation2d> points;
142 if (segments_.empty() || steps_per_segment <= 0.0) {
146 const int sample_count =
static_cast<int>(steps_per_segment);
147 if (sample_count <= 0) {
151 for (
size_t i = 0; i < segments_.size(); ++i) {
152 for (
int step = 0; step < sample_count; ++step) {
153 const double u =
static_cast<double>(step) /
static_cast<double>(sample_count);
154 points.push_back(segments_[i]->position(u));
157 points.push_back(segments_.back()->position(1.0));
162 size_t segment_index_for_s(
double s)
const {
163 auto upper = std::upper_bound(segment_starts_.begin(), segment_starts_.end(), s);
164 if (upper == segment_starts_.begin()) {
167 size_t idx =
static_cast<size_t>((upper - segment_starts_.begin()) - 1);
168 if (idx >= segments_.size()) {
169 idx = segments_.size() - 1;
174 std::vector<std::unique_ptr<SplineBase>> segments_;
175 std::vector<double> segment_starts_;
176 double total_length_ = 0.0;
CubicHermiteSpline()=default
Default constructor.
QuinticHermiteSpline()=default
Default constructor.
static SplinePath from_hermite(const std::vector< HermitePoint > &points, Order order=Order::Quintic, double max_err=1e-4)
Constructs a multi-segment path from a vector of Hermite waypoints.
Definition spline_path.h:66
SplinePath()=default
Default constructor.
double length() const
Definition spline_path.h:88
bool empty() const
Definition spline_path.h:82
static SplinePath from_waypoints(const std::vector< HermitePoint > &points, std::function< std::unique_ptr< SplineBase >(const HermitePoint &, const HermitePoint &, double)> factory, double max_err=1e-4)
Constructs a multi-segment path using a custom Spline factory.
Definition spline_path.h:32
std::vector< Translation2d > sample_by_spacing(double ds) const
Samples 2D positions uniformly spaced by distance ds along the path.
Definition spline_path.h:123
SplineSample sample_by_s(double s) const
Samples complete state at arc distance s along the multi-segment path.
Definition spline_path.h:96
std::vector< Translation2d > sample_by_segment_steps(double steps_per_segment) const
Samples 2D positions with fixed number of steps per spline segment.
Definition spline_path.h:140
Order
Order of spline polynomials used per segment.
Definition spline_path.h:17
@ Quintic
Quintic Hermite splines (C2 continuity).
Definition spline_path.h:19
@ Cubic
Cubic Hermite splines (C1 continuity).
Definition spline_path.h:18
size_t segment_count() const
Definition spline_path.h:85
Represents a boundary point along a Hermite spline.
Definition hermite_point.h:16
Evaluated state sample at a specific parameter u or distance s along a spline.
Definition spline_base.h:14
double s
Arc length along spline from start in inches.
Definition spline_base.h:16