27#ifndef EASY3D_CORE_CURVE_H
28#define EASY3D_CORE_CURVE_H
104 template <
template <
size_t,
class>
class Point,
size_t N,
typename T>
105 void quadratic(
const Point<N, T>& A,
const Point<N, T>& B,
const Point<N, T>& C,
106 std::vector<Point<N, T>>&
curve,
unsigned int bezier_steps = 4,
107 bool include_end =
false)
109 using Point_t = Point<N, T>;
110 for (
unsigned int i = 0; i <= bezier_steps; i++) {
111 const T t =
static_cast<T
>(i) / bezier_steps;
112 const Point_t U = (1.0 - t) * A + t * B;
113 const Point_t V = (1.0 - t) * B + t * C;
114 curve.push_back((1.0 - t) * U + t * V);
171 template <
template <
size_t,
class>
class Point,
size_t N,
typename T>
172 void cubic(
const Point<N, T> &A,
const Point<N, T> &B,
const Point<N, T> &C,
const Point<N, T> &D,
173 std::vector<Point<N, T>> &
curve,
174 unsigned int bezier_steps = 4,
175 bool include_end =
false)
177 using Point_t = Point<N, T>;
178 for (
unsigned int i = 0; i <= bezier_steps; i++) {
179 const T t =
static_cast<T
>(i) / bezier_steps;
180 const Point_t U = (1.0 - t) * A + t * B;
181 const Point_t V = (1.0 - t) * B + t * C;
182 const Point_t W = (1.0 - t) * C + t * D;
183 const Point_t P = (1.0 - t) * U + t * V;
184 const Point_t Q = (1.0 - t) * V + t * W;
185 curve.push_back((1.0 - t) * P + t * Q);
206 template<
template <
size_t,
class>
class Point,
size_t N,
typename T>
218 virtual std::vector<Point_t>
generate(
const std::vector<Point_t> &control_points,
size_t num_samples)
const = 0;
237 template<
template <
size_t,
class>
class Point,
size_t N,
typename T>
252 std::vector<Point_t>
generate(
const std::vector<Point_t> &control_points,
size_t num_samples)
const override {
253 std::vector<Point_t>
curve;
254 curve.reserve(num_samples + 1);
256 for (
size_t i = 0; i <= num_samples; ++i) {
257 T t =
static_cast<T
>(i) / num_samples;
258 curve.push_back(interpolate(control_points, t));
264 Point_t interpolate(
const std::vector<Point_t> &control_points, T t)
const {
265 std::vector<Point_t> points = control_points;
266 size_t n = points.size();
267 for (
size_t k = 1; k < n; ++k) {
268 for (
size_t i = 0; i < n - k; ++i) {
269 points[i] = points[i] * (1 - t) + points[i + 1] * t;
292 template<
template <
size_t,
class>
class Point,
size_t N,
typename T>
307 std::vector<Point_t>
generate(
const std::vector<Point_t> &control_points,
size_t num_samples)
const override {
308 std::vector<Point_t>
curve;
309 size_t n = control_points.size();
313 curve.reserve(num_samples + 1);
316 for (
size_t i = 0; i <= num_samples; ++i) {
317 T t =
static_cast<T
>(i) / num_samples * (n - 3);
318 size_t k =
static_cast<size_t>(t);
328 curve.push_back(interpolate(control_points, t, k));
334 Point_t interpolate(
const std::vector<Point_t> &control_points, T t,
size_t k)
const {
335 const T one_sixth =
static_cast<T
>(1) / 6;
336 Point_t P0 = control_points[k];
337 Point_t P1 = control_points[k + 1];
338 Point_t P2 = control_points[k + 2];
339 Point_t P3 = control_points[k + 3];
344 return (P0 * (-t3 + 3 * t2 - 3 * t + 1) * one_sixth) +
345 (P1 * (3 * t3 - 6 * t2 + 4) * one_sixth) +
346 (P2 * (-3 * t3 + 3 * t2 + 3 * t + 1) * one_sixth) +
347 (P3 * (t3) * one_sixth);
367 template<
template <
size_t,
class>
class Point,
size_t N,
typename T>
382 std::vector<Point_t>
generate(
const std::vector<Point_t> &control_points,
size_t num_samples)
const override {
383 std::vector<Point_t>
curve;
384 curve.reserve(num_samples + 1);
386 for (
size_t i = 0; i <= num_samples; ++i) {
387 T t =
static_cast<T
>(i) / num_samples;
388 curve.push_back(interpolate(control_points, t));
394 Point_t interpolate(
const std::vector<Point_t> &control_points, T t)
const {
395 size_t n = control_points.size() - 3;
396 size_t i = std::min(
static_cast<size_t>(t * n), n - 1);
398 Point_t P0 = control_points[i], P1 = control_points[i + 1], P2 = control_points[i + 2], P3 = control_points[
400 return ((P0 * (-1) + P1 * 3 - P2 * 3 + P3) * (u * u * u) / 2 +
401 (P0 * 2 - P1 * 5 + P2 * 4 - P3) * (u * u) / 2 +
402 (P0 * (-1) + P2) * u / 2 +
Point< N, T > Point_t
The type of points.
Definition curve.h:296
BSpline()=default
Default constructor.
std::vector< Point_t > generate(const std::vector< Point_t > &control_points, size_t num_samples) const override
Generates a curve based on the given control points.
Definition curve.h:307
Bezier()=default
Default constructor.
Point< N, T > Point_t
The type of points.
Definition curve.h:241
std::vector< Point_t > generate(const std::vector< Point_t > &control_points, size_t num_samples) const override
Generates a curve based on the given control points.
Definition curve.h:252
Point< N, T > Point_t
The type of points.
Definition curve.h:371
CatmullRom()=default
Default constructor.
std::vector< Point_t > generate(const std::vector< Point_t > &control_points, size_t num_samples) const override
Generates a curve based on the given control points.
Definition curve.h:382
Abstract base class for curve fitting/interpolation.
Definition curve.h:207
Point< N, T > Point_t
The type of points.
Definition curve.h:210
virtual std::vector< Point_t > generate(const std::vector< Point_t > &control_points, size_t num_samples) const =0
Generates a curve based on the given control points.
Algorithms for evaluating curves.
void quadratic(const Point< N, T > &A, const Point< N, T > &B, const Point< N, T > &C, std::vector< Point< N, T > > &curve, unsigned int bezier_steps=4, bool include_end=false)
Computes a quadratic Bézier curve using De Casteljau’s algorithm.
Definition curve.h:105
void cubic(const Point< N, T > &A, const Point< N, T > &B, const Point< N, T > &C, const Point< N, T > &D, std::vector< Point< N, T > > &curve, unsigned int bezier_steps=4, bool include_end=false)
Evaluates a cubic Bézier curve using De Casteljau’s algorithm.
Definition curve.h:172
Definition collider.cpp:182