39 #include "bezier-to-sbasis.h"
42 #include <boost/optional/optional.hpp>
47 const unsigned size=order+1;
48 std::vector<Coord> vtemp(v,v+size);
51 std::vector<Coord> nodata(size);
52 if(left == NULL)left=&nodata[0];
53 if(right == NULL)right=&nodata[0];
57 right[order]= vtemp[order];
60 for (
unsigned i = 1; i < size; ++i) {
61 for (
unsigned j = 0; j < size - i; ++j) {
62 vtemp[j] = lerp(t, vtemp[j], vtemp[j+1]);
65 right[order-i]=vtemp[order-i];
74 std::vector<Coord> c_;
83 Bezier(
Coord const c[],
unsigned ord) : c_(c,c+ord+1){
88 unsigned int order()
const {
return c_.size()-1;}
89 unsigned int size()
const {
return c_.size();}
94 if ( c_.size() != other.c_.size() ) {
95 c_.resize(other.c_.size());
103 explicit Order(
Bezier const &b) : order(b.order()) {}
104 explicit Order(
unsigned o) : order(o) {}
105 operator unsigned()
const {
return order; }
110 assert(ord.order == order());
119 c_[0] = c0; c_[1] = c1;
124 c_[0] = c0; c_[1] = c1; c_[2] = c2;
129 c_[0] = c0; c_[1] = c1; c_[2] = c2; c_[3] = c3;
132 inline unsigned degree()
const {
return order(); }
135 typedef Coord output_type;
136 inline bool isZero()
const {
137 for(
unsigned i = 0; i <= order(); i++) {
138 if(c_[i] != 0)
return false;
142 inline bool isConstant()
const {
143 for(
unsigned i = 1; i <= order(); i++) {
144 if(c_[i] != c_[0])
return false;
148 inline bool isFinite()
const {
149 for(
unsigned i = 0; i <= order(); i++) {
150 if(!is_finite(c_[i]))
return false;
154 inline Coord at0()
const {
return c_[0]; }
155 inline Coord at1()
const {
return c_[order()]; }
157 inline Coord valueAt(
double t)
const {
158 return subdivideArr(t, &c_[0], NULL, NULL, order());
160 inline Coord operator()(
double t)
const {
return valueAt(t); }
162 inline SBasis toSBasis()
const {
163 return bezier_to_sbasis(&c_[0], order());
167 inline Coord &operator[](
unsigned ix) {
return c_[ix]; }
168 inline Coord const &operator[](
unsigned ix)
const {
return c_[ix]; }
169 inline void setPoint(
unsigned ix,
double val) { c_[ix] = val; }
174 std::vector<Coord> valueAndDerivatives(
Coord t,
unsigned n_derivs)
const {
175 std::vector<Coord> val_n_der;
177 unsigned nn = n_derivs;
180 val_n_der.reserve(n_derivs);
182 std::vector<Coord> d_(c_);
183 for(
unsigned di = 0; di < nn; di++) {
184 val_n_der.push_back(subdivideArr(t, &d_[0], NULL, NULL, order() - di));
185 for(
unsigned i = 0; i < order() - di; i++) {
186 d_[i] = (order()-di)*(d_[i+1] - d_[i]);
190 val_n_der.resize(n_derivs);
194 std::pair<Bezier, Bezier > subdivide(
Coord t)
const {
195 Bezier a(Bezier::Order(*
this)), b(Bezier::Order(*
this));
196 subdivideArr(t, &c_[0], &a.c_[0], &b.c_[0], order());
197 return std::pair<Bezier, Bezier >(a, b);
200 std::vector<double> roots()
const {
201 std::vector<double> solutions;
202 find_bernstein_roots(&c_[0], order(), solutions, 0, 0.0, 1.0);
208 inline Bezier operator+(
const Bezier & a,
double v) {
209 Bezier result = Bezier(Bezier::Order(a));
210 for(
unsigned i = 0; i <= a.order(); i++)
211 result[i] = a[i] + v;
215 inline Bezier operator-(
const Bezier & a,
double v) {
216 Bezier result = Bezier(Bezier::Order(a));
217 for(
unsigned i = 0; i <= a.order(); i++)
218 result[i] = a[i] - v;
222 inline Bezier operator*(
const Bezier & a,
double v) {
223 Bezier result = Bezier(Bezier::Order(a));
224 for(
unsigned i = 0; i <= a.order(); i++)
225 result[i] = a[i] * v;
229 inline Bezier operator/(
const Bezier & a,
double v) {
230 Bezier result = Bezier(Bezier::Order(a));
231 for(
unsigned i = 0; i <= a.order(); i++)
232 result[i] = a[i] / v;
236 inline Bezier reverse(
const Bezier & a) {
237 Bezier result = Bezier(Bezier::Order(a));
238 for(
unsigned i = 0; i <= a.order(); i++)
239 result[i] = a[a.order() - i];
243 inline Bezier portion(
const Bezier & a,
double from,
double to) {
245 std::vector<Coord> res(a.order()+1);
247 if(to == 1) {
return Bezier(a); }
248 subdivideArr(to, &a.c_[0], &res[0], NULL, a.order());
249 return Bezier(&res[0], a.order());
251 subdivideArr(from, &a.c_[0], NULL, &res[0], a.order());
252 if(to == 1)
return Bezier(&res[0], a.order());
253 std::vector<Coord> res2(a.order()+1);
254 subdivideArr((to - from)/(1 - from), &res[0], &res2[0], NULL, a.order());
255 return Bezier(&res2[0], a.order());
259 inline std::vector<Point> bezier_points(
const D2<Bezier > & a) {
260 std::vector<Point> result;
261 for(
unsigned i = 0; i <= a[0].order(); i++) {
263 for(
unsigned d = 0; d < 2; d++) p[d] = a[d][i];
269 inline Bezier derivative(
const Bezier & a) {
270 if(a.order() == 1)
return Bezier(0.0);
271 Bezier der(Bezier::Order(a.order()-1));
273 for(
unsigned i = 0; i < a.order(); i++) {
274 der.c_[i] = a.order()*(a.c_[i+1] - a.c_[i]);
279 inline Bezier integral(
const Bezier & a) {
280 Bezier inte(Bezier::Order(a.order()+1));
283 for(
unsigned i = 0; i < inte.order(); i++) {
284 inte[i+1] = inte[i] + a[i]/(inte.order());
289 inline Interval bounds_fast(Bezier
const & b) {
290 return Interval::fromArray(&b.c_[0], b.size());
294 inline Interval bounds_exact(Bezier
const & b) {
295 return bounds_exact(b.toSBasis());
298 inline Interval bounds_local(Bezier
const & b, Interval i) {
299 return bounds_fast(portion(b, i.min(), i.max()));
303 inline std::ostream &operator<< (std::ostream &out_file,
const Bezier & b) {
304 for(
unsigned i = 0; i < b.size(); i++) {
305 out_file << b[i] <<
", ";
311 #endif //SEEN_BEZIER_H
double Coord
Definition: coord.h:45
Definition: interval.h:56