50#include <gsl/gsl_poly.h>
53 for(
unsigned i = 0; i < p.
size(); i++) {
56 B[1] =
Linear(450) - p[i]*vscale;
68 Point dM0 = dM(t0)*(t1-t0);
70 Point dM1 = dM(t1)*(t1-t0);
72 for (
unsigned dim=0; dim<2; dim++){
74 r[0] =
Linear(M0[dim],M1[dim]);
75 r[1] =
Linear(M0[dim]-M1[dim]+dM0[dim],-(M0[dim]-M1[dim]+dM1[dim]));
83 Point M0,dM0,d2M0,M1,dM1,d2M1,A0,A1;
97 if (candidates.size()==0){
100 double maxlength = -1;
102 for (
unsigned i=0; i<candidates.size(); i++){
103 double l =
length(candidates[i]);
104 if ( l < maxlength || maxlength < 0 ){
109 return candidates[best];
124 h_dist = bnds->extent();
128 return max(bnds.
min().length(), bnds.
max().length());
133 if (t0>=t1)
return 0;
134 if (t0+0.001>=t1)
return 0;
139 if(k_bez[0].
size() > 1 and k_bez[1].
size() > 1) {
144 if(h_dist < precision) {
146 cairo_set_line_width (cr, 0.93);
161 if (t0>=t1)
return 0;
162 if (t0+0.001>=t1)
return 0;
166 if(k_bez[0].
size() > 1 and k_bez[1].
size() > 1) {
175struct quadratic_params
178 double t0, precision;
183 struct quadratic_params *p
184 = (
struct quadratic_params *) params;
190#include <gsl/gsl_errno.h>
191#include <gsl/gsl_math.h>
192#include <gsl/gsl_roots.h>
196 if(t0 >= t1)
return 0;
201 int iter = 0, max_iter = 100;
202 const gsl_root_fsolver_type *T;
205 struct quadratic_params params = {&f, t0, precision};
210 T = gsl_root_fsolver_brent;
211 s = gsl_root_fsolver_alloc (T);
212 gsl_root_fsolver_set (s, &F, t0, t1);
217 status = gsl_root_fsolver_iterate (s);
218 r = gsl_root_fsolver_root (s);
219 double x_lo = gsl_root_fsolver_x_lower (s);
220 double x_hi = gsl_root_fsolver_x_upper (s);
221 status = gsl_root_test_interval (x_lo, x_hi,
226 while (status == GSL_CONTINUE && iter < max_iter);
228 double x_lo = gsl_root_fsolver_x_lower (s);
229 double x_hi = gsl_root_fsolver_x_upper (s);
230 printf (
"%5d [%.7f, %.7f] %.7f %.7f\n",
234 gsl_root_fsolver_free (s);
239 cairo_set_line_width (cr, 0.93);
252class SbToBezierTester:
public Toy {
255 std::vector<Toggle> toggles;
258 void draw(
cairo_t *cr, std::ostringstream *notify,
int width,
int height,
bool save, std::ostringstream *timer_stream)
override {
262 cairo_set_line_width (cr, 0.5);
264 if(!mouses.empty()) {
266 for(
auto & mouse : mouses) {
271 adjuster2.
pos[0]=150;
272 adjuster2.
pos[1]=std::min(std::max(adjuster2.
pos[1],150.),450.);
277 double scale0=(450-adjuster2.
pos[1])/300;
278 double curve_precision =
pow(10, scale0*5-2);
279 val_s << curve_precision;
295 *notify <<
" total segments: "<< segs <<
"\n";
299 toggles[0].bounds =
Rect(p, p + d);
301 toggles[1].bounds =
Rect(p, p + d);
307 void key_hit(
unsigned keyval,
unsigned modifiers)
override {
308 if(keyval ==
's') toggles[0].toggle();
311 vector<Point> mouses;
327 mouses.emplace_back(pos);
340 for (
unsigned i = 2; i < mouses.size(); i += 2) {
354 toggles.emplace_back(
"Seq",
false);
355 toggles.emplace_back(
"Linfty",
true);
359int main(
int argc,
char **argv) {
360 init(argc, argv,
new SbToBezierTester);
Basic intersection routines.
Adaptor that creates 2D functions from 1D ones.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
CPoint max() const
Get the corner of the rectangle with largest coordinate values.
Function that interpolates linearly between two values.
Range of real numbers that can be empty.
Sequence of contiguous curves, aka spline.
Piecewise< D2< SBasis > > toPwSb() const
void append(Curve *curve)
Add a new curve to the end of the path.
Function defined as discrete pieces.
std::vector< double > cuts
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
Polynomial in symmetric power basis.
virtual void mouse_pressed(Geom::Point const &pos, unsigned button, unsigned modifiers)
virtual void mouse_moved(Geom::Point const &pos, unsigned modifiers)
vector< Handle * > handles
virtual void mouse_released(Geom::Point const &pos, unsigned button, unsigned modifiers)
virtual void save(FILE *f)
virtual void key_hit(unsigned keyval, unsigned modifiers)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
Lifts one dimensional objects into 2D.
BezierCurveN< 2 > QuadraticBezier
Quadratic (order 2) Bezier curve.
Various utility functions.
Coord length(LineSegment const &seg)
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
D2< T > compose(D2< T > const &a, T const &b)
Bezier derivative(Bezier const &a)
Piecewise< D2< SBasis > > arc_length_parametrization(D2< SBasis > const &M, unsigned order=3, double tol=.01)
std::vector< D2< SBasis > > cubics_fitting_curvature(Point const &M0, Point const &M1, Point const &dM0, Point const &dM1, double d2M0xdM0, double d2M1xdM1, int insist_on_speed_signs=1, double epsilon=1e-5)
T dot(D2< T > const &a, D2< T > const &b)
OptInterval bounds_fast(Bezier const &b)
Piecewise< SBasis > arcLengthSb(D2< SBasis > const &M, double tol=.01)
D2< T > rot90(D2< T > const &a)
void cairo_line_to(cairo_t *cr, Geom::Point p1)
void draw_handle(cairo_t *cr, Geom::Point h)
void cairo_move_to(cairo_t *cr, Geom::Point p1)
void cairo_d2_sb(cairo_t *cr, Geom::D2< Geom::SBasis > const &p)
void cairo_pw_d2_sb(cairo_t *cr, Geom::Piecewise< Geom::D2< Geom::SBasis > > const &p)
double goal_function(Piecewise< D2< SBasis > >const &A, Piecewise< D2< SBasis > >const &B)
double quadratic(double x, void *params)
void cairo_pw(cairo_t *cr, Piecewise< SBasis > p, double hscale=1., double vscale=1.)
double single_curvature_fitter(Piecewise< D2< SBasis > > const &f, double t0, double t1)
int sequential_curvature_fitter(cairo_t *cr, Piecewise< D2< SBasis > > const &f, double t0, double t1, double precision)
D2< SBasis > naive_sb_seg_to_bez(Piecewise< D2< SBasis > > const &M, double t0, double t1)
int recursive_curvature_fitter(cairo_t *cr, Piecewise< D2< SBasis > > const &f, double t0, double t1, double precision)
D2< SBasis > sb_seg_to_bez(Piecewise< D2< SBasis > > const &M, double t0, double t1)
two-dimensional geometric operators.
Conversion between SBasis and Bezier basis polynomials.
Polynomial in symmetric power basis (S-basis)
void draw_text(cairo_t *cr, Geom::Point pos, const char *txt, bool bottom=false, const char *fontdesc="Sans")
void toggle_events(std::vector< Toggle > &ts, Geom::Point const &pos, unsigned button)
void cairo_set_source_rgba(cairo_t *cr, colour c)
void draw_toggles(cairo_t *cr, std::vector< Toggle > &ts)
void init(int argc, char **argv, Toy *t, int width=600, int height=600)