27#ifndef EASY3D_CORE_CURVE_H
28#define EASY3D_CORE_CURVE_H
77 template<
typename Po
int_t>
79 void quadratic(
const Point_t &A,
const Point_t &B,
const Point_t &C, std::vector<Point_t> &curve,
80 unsigned int bezier_steps = 4,
bool include_end =
false) {
81 typedef typename Point_t::FT FT;
82 for (
unsigned int i = 0; i < bezier_steps; i++) {
83 const FT t =
static_cast<FT
>(i) / bezier_steps;
84 const Point_t U = (1.0 - t) * A + t * B;
85 const Point_t V = (1.0 - t) * B + t * C;
86 curve.push_back((1.0 - t) * U + t * V);
129 template<
typename Po
int_t>
131 void cubic(
const Point_t &A,
const Point_t &B,
const Point_t &C,
const Point_t &D, std::vector<Point_t> &curve,
132 unsigned int bezier_steps = 4,
bool include_end =
false) {
133 typedef typename Point_t::FT FT;
134 for (
unsigned int i = 0; i < bezier_steps; i++) {
135 const FT t =
static_cast<FT
>(i) / bezier_steps;
136 const Point_t U = (1.0 - t) * A + t * B;
137 const Point_t V = (1.0 - t) * B + t * C;
138 const Point_t W = (1.0 - t) * C + t * D;
139 const Point_t M = (1.0 - t) * U + t * V;
140 const Point_t N = (1.0 - t) * V + t * W;
141 curve.push_back((1.0 - t) * M + t * N);
158 template<
typename Po
int_t>
162 typedef typename Point_t::FT
FT;
172 way_points_.push_back(point);
173 on_way_point_added();
177 int node_count()
const {
return static_cast<int>(nodes_.size()); }
180 const Point_t &
node(
int i)
const {
return nodes_[i]; }
187 assert(!distances_.empty());
188 return distances_.back();
199 void add_node(
const Point_t &
node) {
200 nodes_.push_back(
node);
201 if (nodes_.size() == 1)
202 distances_.push_back(0);
204 int new_node_index = nodes_.size() - 1;
205 FT segment_distance =
distance(nodes_[new_node_index], nodes_[new_node_index - 1]);
206 distances_.push_back(segment_distance + distances_[new_node_index - 1]);
210 virtual void on_way_point_added() = 0;
213 interpolate(
FT u,
const Point_t &P0,
const Point_t &P1,
const Point_t &P2,
const Point_t &P3)
const = 0;
217 std::vector<Point_t> way_points_;
218 std::vector<Point_t> nodes_;
219 std::vector<FT> distances_;
236 template<
typename Po
int_t>
240 typedef typename Point_t::FT
FT;
250 void on_way_point_added()
override {
251 if (way_points_.size() < 4)
253 int new_control_point_index = way_points_.size() - 1;
254 if (new_control_point_index == 3) {
255 for (
int i = 0; i <= steps_; i++) {
256 FT u = (
FT) i / (
FT) steps_;
257 add_node(interpolate(u, way_points_[0], way_points_[1], way_points_[2], way_points_[3]));
260 if (new_control_point_index % 2 == 0)
262 int pt = new_control_point_index - 2;
263 for (
int i = 0; i <= steps_; i++) {
264 FT u = (
FT) i / (
FT) steps_;
265 Point_t point4 = 2 * way_points_[pt] - way_points_[pt - 1];
266 add_node(interpolate(u, way_points_[pt], point4, way_points_[pt + 1], way_points_[pt + 2]));
271 Point_t interpolate(
FT u,
const Point_t &P0,
const Point_t &P1,
const Point_t &P2,
272 const Point_t &P3)
const override {
274 point = u * u * u * ((-1) * P0 + 3 * P1 - 3 * P2 + P3);
275 point += u * u * (3 * P0 - 6 * P1 + 3 * P2);
276 point += u * ((-3) * P0 + 3 * P1);
297 template<
typename Po
int_t>
301 typedef typename Point_t::FT
FT;
311 void on_way_point_added()
override {
312 if (way_points_.size() < 4)
314 int new_control_point_index =
static_cast<int>(way_points_.size()) - 1;
315 int pt = new_control_point_index - 3;
316 for (
int i = 0; i <= steps_; i++) {
317 FT u = (
FT) i / (
FT) steps_;
318 add_node(interpolate(u, way_points_[pt], way_points_[pt + 1], way_points_[pt + 2],
319 way_points_[pt + 3]));
323 Point_t interpolate(
FT u,
const Point_t &P0,
const Point_t &P1,
const Point_t &P2,
324 const Point_t &P3)
const override {
326 point = u * u * u * ((-1) * P0 + 3 * P1 - 3 * P2 + P3) / 6;
327 point += u * u * (3 * P0 - 6 * P1 + 3 * P2) / 6;
328 point += u * ((-3) * P0 + 3 * P2) / 6;
329 point += (P0 + 4 * P1 + P2) / 6;
351 template<
typename Po
int_t>
355 typedef typename Point_t::FT
FT;
365 void on_way_point_added()
override {
366 if (way_points_.size() < 4)
368 int new_control_point_index = way_points_.size() - 1;
369 int pt = new_control_point_index - 2;
370 for (
int i = 0; i <= steps_; i++) {
371 FT u = (
FT) i / (
FT) steps_;
372 add_node(interpolate(u, way_points_[pt - 1], way_points_[pt], way_points_[pt + 1],
373 way_points_[pt + 2]));
377 Point_t interpolate(
FT u,
const Point_t &P0,
const Point_t &P1,
const Point_t &P2,
378 const Point_t &P3)
const override {
380 point = u * u * u * ((-1) * P0 + 3 * P1 - 3 * P2 + P3) / 2;
381 point += u * u * (2 * P0 - 5 * P1 + 4 * P2 - P3) / 2;
382 point += u * ((-1) * P0 + P2) / 2;
Class for BSpline curve fitting. Works for both 2D and 3D. Example:
Definition: curve.h:298
BSpline()=default
Default constructor.
Point_t::FT FT
The floating-point number type.
Definition: curve.h:301
Class for Bezier curve fitting. Works for both 2D and 3D. Example:
Definition: curve.h:237
Bezier()=default
Default constructor.
Point_t::FT FT
The floating-point number type.
Definition: curve.h:240
Class for CatmullRom curve interpolation. Works for both 2D and 3D. Example:
Definition: curve.h:352
CatmullRom()=default
Default constructor.
Point_t::FT FT
The floating-point number type.
Definition: curve.h:355
Base class for curve fitting/interpolation.
Definition: curve.h:159
void set_steps(int steps)
Set the number of steps.
Definition: curve.h:168
FT total_length() const
Return the total length of the curve.
Definition: curve.h:186
int node_count() const
Return the number of nodes.
Definition: curve.h:177
FT length_from_start_point(int i) const
Return the total curve length from the start point.
Definition: curve.h:183
Curve()
Default constructor.
Definition: curve.h:165
Point_t::FT FT
The floating-point number type.
Definition: curve.h:162
void add_way_point(const Point_t &point)
Add a way point.
Definition: curve.h:171
void clear()
Clear all cached values.
Definition: curve.h:192
const Point_t & node(int i) const
Return the coordinates of the i_th node.
Definition: curve.h:180
void quadratic(const Point_t &A, const Point_t &B, const Point_t &C, std::vector< Point_t > &curve, unsigned int bezier_steps=4, bool include_end=false)
De Casteljau algorithm evaluating a quadratic or conic (second degree) curve from the given control p...
Definition: curve.h:79
void cubic(const Point_t &A, const Point_t &B, const Point_t &C, const Point_t &D, std::vector< Point_t > &curve, unsigned int bezier_steps=4, bool include_end=false)
De Casteljau algorithm evaluating a cubic (third degree) curve from the given control points A,...
Definition: curve.h:131
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