32#include <2geom/arc-length.h>
42 for(
int i = 0; i < 3; i++)
47 double err = fabs(
dot(orth, v[1])) + fabs(
dot(orth, v[0]));
49 return distance(e.first(), e.last());
53 for(
int i = 0; i < 3; i++)
54 mid[i] =
lerp(0.5, e[i], e[i+1]);
56 for(
int i = 0; i < 2; i++)
57 midmid[i] =
lerp(0.5, mid[i], mid[i+1]);
58 Point midmidmid =
lerp(0.5, midmid[0], midmid[1]);
60 Point curve[4] = {e[0], mid[0], midmid[0], midmidmid};
61 Path::Elem e0(cubicto, std::vector<Point>::const_iterator(
curve), std::vector<Point>::const_iterator(
curve) + 4);
64 Point curve[4] = {midmidmid, midmid[1], mid[2], e[3]};
65 Path::Elem e1(cubicto, std::vector<Point>::const_iterator(
curve), std::vector<Point>::const_iterator(
curve) + 4);
79 if(
dynamic_cast<LineTo *
>(iter.cmd()))
81 else if(
dynamic_cast<CubicTo *
>(iter.cmd()))
92#include <gsl/gsl_integration.h>
95 return hypot(pc[0].eval(t), pc[1].eval(t));
106 if(
dynamic_cast<LineTo *
>(iter.cmd()))
108 else if(
dynamic_cast<QuadTo *
>(iter.cmd()) ||
109 dynamic_cast<CubicTo *
>(iter.cmd())) {
110 Poly B[2] = {get_parametric_poly(pe,
X), get_parametric_poly(pe,
Y)};
111 for(
int i = 0; i < 2; i++)
115 gsl_integration_workspace *
w
116 = gsl_integration_workspace_alloc (20);
119 double quad_result, err;
122 gsl_integration_qag (&F, 0, t, 0, tol, 20,
123 GSL_INTEG_GAUSS21,
w, &quad_result, &err);
133 double result = 0, abserr = 0;
145 double result = 0, abserr = 0;
152 (iter != pl.it); ++iter) {
165#include <gsl/gsl_errno.h>
166#include <gsl/gsl_math.h>
167#include <gsl/gsl_roots.h>
169struct arc_length_params
172 double s,tol,
result, abs_error;
179 struct arc_length_params *p
180 = (
struct arc_length_params *) params;
182 double result = 0, abs_error = 0;
185 if(!((t >= 0) && (t <= 1))) {
186 printf(
"t = %g\n", t);
188 assert((t >= 0) && (t <= 1));
196 struct arc_length_params *p
197 = (
struct arc_length_params *) params;
200 p->pe.point_tangent_acc_at(t, pos, tgt, acc);
206 double *y,
double *dy)
214 int iter = 0, max_iter = 10;
215 const gsl_root_fsolver_type *T;
216 gsl_root_fsolver *solver;
217 double x_lo = 0.0, x_hi = 1.0;
223 T = gsl_root_fsolver_brent;
224 solver = gsl_root_fsolver_alloc (T);
225 gsl_root_fsolver_set (solver, &F, x_lo, x_hi);
230 status = gsl_root_fsolver_iterate (solver);
231 t = gsl_root_fsolver_root (solver);
232 x_lo = gsl_root_fsolver_x_lower (solver);
233 x_hi = gsl_root_fsolver_x_upper (solver);
234 status = gsl_root_test_interval (x_lo, x_hi,
241 while (status == GSL_CONTINUE && iter < max_iter);
245double polish (
double t, arc_length_params &alp) {
247 int iter = 0, max_iter = 5;
248 const gsl_root_fdfsolver_type *T;
249 gsl_root_fdfsolver *solver;
251 gsl_function_fdf FDF;
258 T = gsl_root_fdfsolver_newton;
259 solver = gsl_root_fdfsolver_alloc (T);
260 gsl_root_fdfsolver_set (solver, &FDF, t);
265 status = gsl_root_fdfsolver_iterate (solver);
267 t = gsl_root_fdfsolver_root (solver);
268 status = gsl_root_test_delta (t, t0, 0, alp.tol);
270 if (status == GSL_SUCCESS)
273 printf (
"%5d %10.7f %+10.7f\n",
276 while (status == GSL_CONTINUE && iter < max_iter);
double arc_length_subdividing(Path const &p, double tol)
Calculates the length of a path through iteration and subsequent subdivision.
double polish(double t, arc_length_params &alp)
void arc_length_integrating(Path::Elem pe, double t, double tol, double &result, double &abs_error)
Calculates the length of a path Element through gsl integration.
static double poly_length_integrating(double t, void *param)
double polish_brent(double t, arc_length_params &alp)
double cubic_length_subdividing(Path::Elem const &e, double tol)
Calculates the length of a cubic element through subdivision.
double arc_length_deriv(double t, void *params)
double arc_length(double t, void *params)
void arc_length_fdf(double t, void *params, double *y, double *dy)
Bezier fitting algorithms.
Sequence of contiguous curves, aka spline.
const_iterator end() const
size_type size() const
Natural size of the path.
const_iterator begin() const
Two-dimensional point that doubles as a vector.
void normalize()
Normalize the vector representing the point.
Polynomial in canonical (monomial) basis.
constexpr Coord lerp(Coord t, Coord a, Coord b)
Numerically stable linear interpolation.
Various utility functions.
Angle distance(Angle const &a, Angle const &b)
Bezier derivative(Bezier const &a)
SBasis L2(D2< SBasis > const &a, unsigned k)
T dot(D2< T > const &a, D2< T > const &b)
D2< T > rot90(D2< T > const &a)
Polynomial in canonical (monomial) basis.