45#if defined(__GNUC__) && !defined(__clang__)
46#pragma GCC diagnostic ignored "-Wnonnull"
56 std::vector<Coord> val_n_der(n_derivs + 1,
Coord(0.0));
59 std::valarray<Coord> d_(
order()+1);
60 for(
unsigned i = 0; i <
size(); i++) {
64 unsigned nn = n_derivs + 1;
65 if(n_derivs >
order()) {
68 for(
unsigned di = 0; di < nn; di++) {
71 for(
unsigned i = 0; i <
order() - di; i++) {
72 d_[i] = (
order()-di)*(d_[i+1] - d_[i]);
85 casteljau_subdivision<double>(t, &
c_[0],
88 casteljau_subdivision<double>(t, &
c_[0],
89 &left->
c_[0],
nullptr,
order());
93 casteljau_subdivision<double>(t, &
c_[0],
94 nullptr, &right->
c_[0],
order());
100 std::pair<Bezier, Bezier> ret;
126 for (
int i = 0; i < n; i++) {
128 int b = (i & 1) ? -1 : 1;
129 for (
int j = i; j < n; j++) {
144 for(
unsigned i = 1; i < n; i++) {
145 ed[i] = (i*
c_[i-1] + (n - i)*
c_[i])/(n);
152 if(
order() == 0)
return *
this;
157 unsigned middle = n/2;
158 for(
unsigned i = 1; i < middle; i++) {
159 ed[i] = (n*
c_[i] - i*ed[i-1])/(n-i);
161 for(
unsigned i = n-1; i >= middle; i--) {
162 ed[i] = (n*
c_[i] - i*ed[n-i])/(i);
170 for(
unsigned i =
degree(); i < newDegree; i++) {
178 if(
order() == 0)
return *
this;
179 unsigned n =
order();
181 for(
unsigned i = 0; i < n; i++) {
182 b[i] = (n*
c_[i+1])/(i+1);
197 if (
c_.size() > other.
size()) {
199 }
else if (
c_.size() < other.
size()) {
210 if (
c_.size() > other.
size()) {
212 }
else if (
c_.size() < other.
size()) {
229 for (
int i = 0; i <= m; i++) {
230 double const fi = mci * f[i];
233 for (
int j = 0; j <= n; j++) {
234 h[i + j] += fi * ncj * g[j];
242 for (
int k = 0; k <= m + n; k++) {
254 bool reverse_result =
false;
257 reverse_result =
true;
265 casteljau_subdivision<double>(to, &ret.
c_[0], &ret.
c_[0],
nullptr, ret.
order());
268 casteljau_subdivision<double>(from, &ret.
c_[0], NULL, &ret.
c_[0], ret.
order());
270 casteljau_subdivision<double>((to - from) / (1 - from), &ret.
c_[0], &ret.
c_[0], NULL, ret.
order());
276 if (reverse_result) {
277 std::reverse(&ret.
c_[0], &ret.
c_[0] + ret.
c_.size());
288 for(
unsigned i = 0; i < a.
order(); i++) {
299 for(
unsigned i = 0; i < inte.
order(); i++) {
300 inte[i+1] = inte[i] + a[i]/(inte.
order());
357 auto a = (x2 - x1) - (x1 - x0);
363 if (t > 0.0 && t < 1.0) {
365 auto x = s * s * x0 + 2 * s * t * x1 + t * t * x2;
381 auto a = (x3 - x0) - 3 * (x2 - x1);
382 auto b = (x2 - x1) - (x1 - x0);
385 auto expand = [&] (
Coord t) {
386 if (t > 0.0 && t < 1.0) {
388 auto x = s * s * s * x0 + 3 * s * s * t * x1 + 3 * t * t * s * x2 + t * t * t * x3;
396 expand(-
c / (2 * b));
399 auto d2 = b * b - a *
c;
401 auto bsign = b >= 0.0 ? 1 : -1;
402 auto tmp = -(b + bsign * std::sqrt(d2));
Bernstein-Bezier polynomial.
Calculation of binomial cefficients.
Polynomial in Bernstein-Bezier basis.
std::vector< Coord > valueAndDerivatives(Coord t, unsigned n_derivs) const
Bezier elevate_to_degree(unsigned newDegree) const
void subdivide(Coord t, Bezier *left, Bezier *right) const
Bezier forward_difference(unsigned k) const
void find_bezier_roots(std::vector< double > &solutions, double l, double r) const
std::vector< Coord > roots() const
Bezier reduce_degree() const
Bezier elevate_degree() const
Bezier & operator+=(double v)
std::valarray< Coord > c_
Coord valueAt(double t) const
Bezier & operator-=(double v)
constexpr void expandTo(C val)
Extend the interval to include the given number.
constexpr bool contains(C val) const
Check whether the interval includes this number.
Range of real numbers that is never empty.
static Interval from_array(Coord const *c, unsigned n)
Create an interval from a C-style array of values it should contain.
Range of real numbers that can be empty.
Polynomial in symmetric power basis.
Template concepts used by 2Geom.
double Coord
Floating point type used to store coordinates.
constexpr Coord EPSILON
Default "acceptably small" value.
Various utility functions.
OptInterval bounds_exact(Bezier const &b)
OptInterval bounds_local(Bezier const &b, OptInterval const &i)
constexpr void binomial_increment_k(T &b, int n, int k)
Given a multiple of binomial(n, k), modify it to the same multiple of binomial(n, k + 1).
void find_bernstein_roots(double const *w, unsigned degree, std::vector< double > &solutions, unsigned depth, double left_t=0, double right_t=1, bool use_secant=true)
Bezier operator*(Bezier const &f, Bezier const &g)
Bezier portion(const Bezier &a, double from, double to)
Bezier integral(Bezier const &a)
Bezier derivative(Bezier const &a)
T bernstein_value_at(double t, T const *c_, unsigned n)
Compute the value of a Bernstein-Bezier polynomial.
OptInterval bounds_fast(Bezier const &b)
void bezier_expand_to_image(Interval &range, Coord x0, Coord x1, Coord x2)
Expand an interval to the image of a Bézier-Bernstein polynomial, assuming it already contains the in...
SBasis bezier_to_sbasis(Coord const *handles, unsigned order)
std::vector< double > & solutions
Finding roots of Bernstein-Bezier polynomials.