solve-bezier-parametric.cpp revision c8589a6c7367d09fa756755cef0dd448c7328a71
#include <algorithm>
namespace Geom{
/*** Find the zeros of the parametric function in 2d defined by two beziers X(t), Y(t). The code subdivides until it happy with the linearity of the bezier. This requires an n^2 subdivision for each step, even when there is only one solution.
*
* Perhaps it would be better to subdivide particularly around nodes with changing sign, rather than simply cutting in half.
*/
/*
* Forward declarations
*/
unsigned degree,
double t,
unsigned
static unsigned
static double
unsigned total_steps, total_subs;
/*
* find_bezier_roots : Given an equation in Bernstein-Bezier form, find all
* of the roots in the interval [0, 1]. Return the number of roots found.
*/
void
unsigned degree, /* The degree of the polynomial */
unsigned depth) /* The depth of the recursion */
{
total_steps++;
switch (max_crossings) {
case 0: /* No solutions here */
return;
case 1:
/* Unique solution */
/* Stop recursion when the tree is deep enough */
/* if deep enough, return 1 solution at midpoint */
return;
}
// I thought secant method would be faster here, but it'aint. -- njh
if (control_poly_flat_enough(w, degree)) {
return;
}
break;
}
/* Otherwise, solve recursively after subdividing control polygon */
//Geom::Point Left[degree+1], /* New left and right */
// Right[degree+1]; /* control polygons */
total_subs ++;
}
/*
* crossing_count:
* Count the number of times a Bezier control polygon
* crosses the 0-axis. This number is >= the number of roots.
*
*/
unsigned
unsigned degree) /* Degree of Bezier curve */
{
unsigned n_crossings = 0; /* Number of zero-crossings */
for (unsigned i = 1; i <= degree; i++) {
n_crossings++;
}
return n_crossings;
}
/*
* control_poly_flat_enough :
* Check if the control polygon of a Bezier curve is flat enough
* for recursive subdivision to bottom out.
*
*/
static unsigned
unsigned degree) /* Degree of polynomial */
{
/* Find the perpendicular distance from each interior control point to line connecting V[0] and
* V[degree] */
/* Derive the implicit equation for line connecting first */
/* and last control points */
const double abSquared = (a * a) + (b * b);
//double distance[degree]; /* Distances from pts to line */
for (unsigned i = 1; i < degree; i++) {
/* Compute distance from each of the points to that line */
if (d < 0.0)
}
// Find the largest distance
double max_distance_above = 0.0;
double max_distance_below = 0.0;
for (unsigned i = 0; i < degree-1; i++) {
const double d = distance[i];
if (d < 0.0)
if (d > 0.0)
}
const double intercept_1 = (c + max_distance_above) / -a;
const double intercept_2 = (c + max_distance_below) / -a;
/* Compute bounding interval*/
return 1;
return 0;
}
/*
* compute_x_intercept :
* Compute intersection of chord from first control point to last
* with 0-axis.
*
*/
static double
unsigned degree) /* Degree of curve */
{
}
/*
* Bezier :
* Evaluate a Bezier curve at a particular parameter value
* Fill in control points for resulting sub-curves.
*
*/
unsigned degree, /* Degree of bezier curve */
double t, /* Parameter value */
{
//Geom::Point Vtemp[degree+1][degree+1];
/* Copy control points */
/* Triangle computation */
for (unsigned i = 1; i <= degree; i++) {
for (unsigned j = 0; j <= degree - i; j++) {
}
}
for (unsigned j = 0; j <= degree; j++)
for (unsigned j = 0; j <= degree; j++)
}
};
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :