Easy3D 2.6.1
Loading...
Searching...
No Matches
spline_curve_interpolation.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_CORE_SPLINE_CURVE_INTERPOLATION_H
28#define EASY3D_CORE_SPLINE_CURVE_INTERPOLATION_H
29
30
31#include <vector>
32#include <cassert>
33
34#include <easy3d/core/spline_interpolation.h>
35
36
37namespace easy3d {
38
39
63 template <template <size_t, class> class Point, size_t N, typename T>
65 public:
67 using Point_t = Point<N, T>;
68
74
75 public:
76
82 left_value_(0.0), right_value_(0.0), dim_(0), largest_t_(0.0) {
83 }
84
89 void set_boundary(BoundaryType left, T left_value,
90 BoundaryType right, T right_value);
91
100 void set_points(const std::vector<T> &parameters, const std::vector<Point_t> &points, bool cubic_spline = true);
101
110 void set_points(const std::vector<Point_t> &points, bool cubic_spline = true);
111
117 Point<N, T> eval_f(T u) const;
118
119 private:
120 // -------------------------------------------------------------------------
122 // -------------------------------------------------------------------------
123 BoundaryType left_, right_;
124 T left_value_, right_value_;
125
126 std::size_t dim_;
127 std::vector< SplineInterpolation<T> > interpolators_;
128 T largest_t_;
129 };
130
131
132
133 // Cubic spline interpolation implementation
134 // -----------------------
135
136 template <template <size_t, class> class Point, size_t N, typename T>
138 BoundaryType right, T right_value) {
139 assert(interpolators_.size() == 0); // set_points() must not have happened yet
140 left_ = left;
141 right_ = right;
142 left_value_ = left_value;
143 right_value_ = right_value;
144 }
145
146
147 template <template <size_t, class> class Point, size_t N, typename T>
148 void SplineCurveInterpolation<Point, N, T>::set_points(const std::vector<T> &input_parameters,
149 const std::vector<Point<N, T>> &input_points, bool cubic_spline) {
150 if (input_parameters.empty() || input_parameters.size() != input_points.size())
151 return;
152
153 // filter out non-monotone data
154 std::vector<T> parameters;
155 std::vector<Point<N, T>> points;
156 for (std::size_t i=0; i<input_parameters.size(); ++i) {
157 const T para = input_parameters[i];
158 if (i == 0 || para > parameters.back()) {
159 parameters.push_back(para);
160 points.push_back(input_points[i]);
161 }
162 }
163 const auto diff = input_points.size() - points.size();
164 LOG_IF(diff > 0, WARNING) << diff << " data points discarded because the input has to be monotonously increasing";
165
166 dim_ = points[0].dimension();
167 largest_t_ = parameters.back();
168
169 // an ND curve is represented in the parametric form: x1(t), x2(t), x3(t)...
170 std::vector< std::vector<T> > coords(dim_, std::vector<T>(points.size()));
171
172 T t(0);
173 for (std::size_t i = 0; i < points.size(); ++i) {
174 const auto &p = points[i];
175 if (i > 0)
176 t += distance(points[i-1], p);
177 for (std::size_t j = 0; j<dim_; ++j)
178 coords[j][i] = p[j];
179 }
180
181 // class instantiation
182 interpolators_.resize(dim_);
183 for (std::size_t i=0; i<dim_; ++i) {
184 // set boundary condition
185 interpolators_[i].set_boundary(
187 left_value_,
189 right_value_,
190 cubic_spline
191 );
192 // set data
193 interpolators_[i].set_data(parameters, coords[i]);
194 }
195 }
196
197
198 template <template <size_t, class> class Point, size_t N, typename T>
199 void SplineCurveInterpolation<Point, N, T>::set_points(const std::vector<Point<N, T>> &points, bool cubic_spline) {
200 if (points.size() < 2)
201 return;
202
203 // we use the accumulated curve distance as the parameters
204 std::vector<T> parameters(points.size(), T(0));
205
206 T t(0);
207 for (std::size_t i = 1; i < points.size(); ++i) {
208 const auto &p = points[i];
209 t += distance(points[i-1], p);
210 parameters[i] = t;
211 }
212
213 set_points(parameters, points, cubic_spline);
214 }
215
216
217 template <template <size_t, class> class Point, size_t N, typename T>
219 Point<N, T> p;
220 for (std::size_t i=0; i<dim_; ++i)
221 p[i] = interpolators_[i](u * largest_t_);
222 return p;
223 }
224
225
226} // namespace easy3d
227
228
229#endif // EASY3D_CORE_SPLINE_CURVE_INTERPOLATION_H
void set_boundary(BoundaryType left, T left_value, BoundaryType right, T right_value)
Definition spline_curve_interpolation.h:137
void set_points(const std::vector< T > &parameters, const std::vector< Point_t > &points, bool cubic_spline=true)
Definition spline_curve_interpolation.h:148
Point< N, T > Point_t
The point type.
Definition spline_curve_interpolation.h:67
Point< N, T > eval_f(T u) const
Definition spline_curve_interpolation.h:218
SplineCurveInterpolation()
Definition spline_curve_interpolation.h:81
BoundaryType
The boundary type.
Definition spline_curve_interpolation.h:70
@ first_deriv
First derivative.
Definition spline_curve_interpolation.h:71
@ second_deriv
Second derivative.
Definition spline_curve_interpolation.h:72
@ first_deriv
first derivative
Definition spline_interpolation.h:90
@ second_deriv
second derivative
Definition spline_interpolation.h:91
Definition collider.cpp:182
T distance(const Vec< N, T > &v1, const Vec< N, T > &v2)
Computes the distance between two vectors/points.
Definition vec.h:295