37#define EPSILON (ldexp(1.0,-MAXDEPTH-1))
53 double t_candidate[W_DEGREE];
59 int n_solutions =
FindRoots(
w, W_DEGREE, t_candidate, 0);
67 for (
int i = 0; i < n_solutions; i++) {
70 if (new_dist < dist) {
95 static double z[3][4] = {
104 for (
int i = 0; i <= DEGREE; i++) {
109 for (
int i = 0; i <= DEGREE - 1; i++) {
110 d[i] = 3.0*(V[i+1] - V[i]);
115 for (
int row = 0; row <= DEGREE - 1; row++) {
116 for (
int column = 0; column <= DEGREE; column++) {
117 cdTable[row][column] =
dot(d[row],
c[column]);
124 for (
int i = 0; i <= W_DEGREE; i++) {
126 w[i][
Geom::X] = (double)(i) / W_DEGREE;
129 const int n = DEGREE;
130 const int m = DEGREE-1;
131 for (
int k = 0; k <= n + m; k++) {
132 const int lb = std::max(0, k - m);
133 const int ub = std::min(k, n);
134 for (
int i = lb; i <= ub; i++) {
136 w[i+j][
Geom::Y] += cdTable[j][i] * z[j][i];
161 double left_t[W_DEGREE+1],
192 for (i = 0; i < left_count; i++) {
195 for (i = 0; i < right_count; i++) {
196 t[i+left_count] = right_t[i];
200 return (left_count+right_count);
218 for (
int i = 1; i <=
degree; i++) {
220 if (
sign != old_sign)
241 double max_distance_above;
242 double max_distance_below;
255 distance = (
double *)malloc((
unsigned)(
degree + 1) *
sizeof(
double));
265 abSquared = (a * a) + (b * b);
267 for (i = 1; i <
degree; i++) {
281 max_distance_above = 0.0;
282 max_distance_below = 0.0;
283 for (i = 1; i <
degree; i++) {
285 max_distance_below = std::min(max_distance_below,
distance[i]);
288 max_distance_above = std::max(max_distance_above,
distance[i]);
295 double a1, b1, c1, a2, b2, c2;
305 c2 =
c + max_distance_above;
307 det = a1 * b2 - a2 * b1;
309 intercept_1 = (b1 * c2 - b2 * c1) /
det;
314 c2 =
c + max_distance_below;
316 det = a1 * b2 - a2 * b1;
318 intercept_2 = (b1 * c2 - b2 * c1) /
det;
322 left_intercept = std::min(intercept_1, intercept_2);
323 right_intercept = std::max(intercept_1, intercept_2);
325 error = 0.5 * (right_intercept-left_intercept);
326 if (error < EPSILON) {
370 for (
int j =0; j <=
degree; j++) {
375 for (
int i = 1; i <=
degree; i++) {
376 for (
int j =0 ; j <=
degree - i; j++) {
378 (1.0 - t) * Vtemp[i-1][j] + t * Vtemp[i-1][j+1];
383 for (
int j = 0; j <=
degree; j++) {
384 Left[j] = Vtemp[j][0];
388 for (
int j = 0; j <=
degree; j++) {
389 Right[j] = Vtemp[
degree-j][j];
393 return (Vtemp[
degree][0]);
double distance(Shape const *s, Geom::Point const &p)
Two-dimensional point that doubles as a vector.
static T det(T a, T b, T c, T d)
int sgn(const T &x)
Sign function - indicates the sign of a numeric type.
static double SquaredLength(const Geom::Point a)
double NearestPointOnCurve(Geom::Point P, Geom::Point *V)
static int ControlPolygonFlatEnough(Geom::Point *V, int degree)
static int FindRoots(Geom::Point *w, int degree, double *t, int depth)
static int CrossingCount(Geom::Point *V, int degree)
static double ComputeXIntercept(Geom::Point *V, int degree)
static Geom::Point Bez(Geom::Point *V, int degree, double t, Geom::Point *Left, Geom::Point *Right)
static Geom::Point * ConvertToBezierForm(Geom::Point P, Geom::Point *V)
static double sign(double const x)
Returns -1 or 1 according to the sign of x.
void dot(Cairo::RefPtr< Cairo::Context > &cr, double x, double y)