solve-bezier-one-d.cpp revision 8001ba81cb851b38d86650a2fef5817facffb763
#include <algorithm>
/*** Find the zeros of the bernstein function. The code subdivides until it is happy with the
* linearity of the function. This requires an O(degree^2) subdivision for each step, even when
* there is only one solution.
*/
namespace Geom{
template<class t>
const unsigned MAXDEPTH = 23; // Maximum depth for recursion. Using floats means 23 bits precision max
/**
* This function is called _a lot_. We have included various manual memory management stuff to reduce the amount of mallocing that goes on. In the future it is possible that this will hurt performance.
**/
class Bernsteins{
public:
double *Vtemp;
unsigned N,degree;
Vtemp = new double[N*2];
}
~Bernsteins() {
delete[] Vtemp;
}
void subdivide(double const *V,
double t,
double *Left,
double *Right);
unsigned
control_poly_flat_enough(double const *V);
void
find_bernstein_roots(double const *w, /* The control points */
unsigned depth, /* The depth of the recursion */
};
/*
* find_bernstein_roots : Given an equation in Bernstein-Bernstein form, find all
* of the roots in the open interval (0, 1). Return the number of roots found.
*/
void
find_bernstein_roots(double const *w, /* The control points */
unsigned degree, /* The degree of the polynomial */
unsigned depth, /* The depth of the recursion */
{
}
void
unsigned depth, /* The depth of the recursion */
{
unsigned n_crossings = 0; /* Number of zero-crossings */
for (unsigned i = 1; i < N; i++) {
if (sign) {
n_crossings++;
}
}
}
if (n_crossings == 0) // no solutions here
return;
if (n_crossings == 1) {
/* Unique solution */
/* Stop recursion when the tree is deep enough */
/* if deep enough, return 1 solution at midpoint */
//printf("bottom out %d\n", depth);
return;
return;
}
// I thought secant method would be faster here, but it'aint. -- njh
// The original code went to some effort to try and terminate early when the curve is sufficiently flat. However, it seems that in practice it almost always bottoms out, so leaving this code out actually speeds things up
if(0) if (control_poly_flat_enough(w)) {
//printf("flatten out %d\n", depth);
return;
}
}
/* Otherwise, solve recursively after subdividing control polygon */
double Left[N], /* New left and right */
Right[N]; /* control polygons */
const double t = 0.5;
/*
* Bernstein :
* Evaluate a Bernstein function at a particular parameter value
* Fill in control points for resulting sub-curves.
*
*/
for (unsigned i = 0; i < N; i++)
Vtemp[i] = w[i];
/* Triangle computation */
const double omt = (1-t);
for (unsigned i = 1; i < N; i++) {
for (unsigned j = 0; j < N - i; j++) {
}
}
/* Solution is exactly on the subdivision point. */
if (Right[0] == 0)
}
/*
* control_poly_flat_enough :
* Check if the control polygon of a Bernstein curve is flat enough
* for recursive subdivision to bottom out.
*
*/
unsigned
Bernsteins::control_poly_flat_enough(double const *V)
{
/* 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 a = V[0] - V[degree];
double max_distance_above = 0.0;
double max_distance_below = 0.0;
for (unsigned i = 1; i < degree; i++) {
/* Compute distance from each of the points to that line */
const double d = (a + V[i]) * ii - a;
double dist = d*d;
// Find the largest distance
if (d < 0.0)
else
}
/* Compute bounding interval*/
//printf("error %g %g %g\n", error, a, BEPSILON * a);
}
};
/*
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:encoding=utf-8:textwidth=99 :