28 #ifndef __ETL__BEZIER_H
29 #define __ETL__BEZIER_H
42 #define SGN(a) (((a)<0) ? -1 : 1)
46 #define MIN(a,b) (((a)<(b))?(a):(b))
51 #define MAX(a,b) (((a)>(b))?(a):(b))
54 #define BEZIER_EPSILON (ldexp(1.0,-MAXDEPTH-1))
65 template<
typename V,
typename T>
class bezier;
70 template <
typename V,
typename T=
float>
89 a(a),b(b),c(c),d(d),
r(
r),
s(
s) {
sync(); }
227 class bezier_base<float,float> :
public std::unary_function<float,float>
244 a(a),b(b),c(c),d(d),
r(
r),
s(
s),drs(1.0/(
s-
r)) {
sync(); }
250 _coeff[1]=
b*3 -
a*3;
251 _coeff[2]=
c*3 -
b*6 + a*3;
252 _coeff[3]=
d -
c*3 +
b*3 -
a;
258 { t-=
r; t*=drs;
return _coeff[0]+(_coeff[1]+(_coeff[2]+(_coeff[3])*t)*t)*t; }
275 system[0]=_coeff[0]-x._coeff[0];
276 system[1]=_coeff[1]-x._coeff[1];
277 system[2]=_coeff[2]-x._coeff[2];
278 system[3]=_coeff[3]-x._coeff[3];
286 t-= (system[0]+(system[1]+(system[2]+(system[3])*t)*t)*t)/
287 (system[1]+(system[2]*2+(system[3]*3)*t)*t);
307 class bezier_base<double,float> :
public std::unary_function<float,double>
324 a(a),b(b),c(c),d(d),
r(
r),
s(
s),drs(1.0/(
s-
r)) {
sync(); }
330 _coeff[1]=
b*3 -
a*3;
331 _coeff[2]=
c*3 -
b*6 + a*3;
332 _coeff[3]=
d -
c*3 +
b*3 -
a;
338 { t-=
r; t*=drs;
return _coeff[0]+(_coeff[1]+(_coeff[2]+(_coeff[3])*t)*t)*t; }
355 system[0]=_coeff[0]-x._coeff[0];
356 system[1]=_coeff[1]-x._coeff[1];
357 system[2]=_coeff[2]-x._coeff[2];
358 system[3]=_coeff[3]-x._coeff[3];
366 t-= (system[0]+(system[1]+(system[2]+(system[3])*t)*t)*t)/
367 (system[1]+(system[2]*2+(system[3]*3)*t)*t);
473 template <
typename V,
typename T>
522 template <
typename V,
typename T=
float>
566 if(
dist(this->
operator()((s-
r)*(1.0/3.0)+
r), x) <
567 dist(this->
operator()((s-
r)*(2.0/3.0)+
r), x))
584 for(r+=inc;r<
s;r+=inc)
646 if(right) *right = rt;
691 for (j = 0; j <= degree; j++)
695 for (i = 1; i <= degree; i++)
696 for (j =0 ; j <= degree - i; j++)
698 Vtemp[i][j][0] = (1.0 - t) * Vtemp[i-1][j][0] + t * Vtemp[i-1][j+1][0];
699 Vtemp[i][j][1] = (1.0 - t) * Vtemp[i-1][j][1] + t * Vtemp[i-1][j+1][1];
703 for (j = 0; j <= degree; j++)
704 Left[j] = Vtemp[j][0];
707 for (j = 0; j <= degree; j++)
708 Right[j] = Vtemp[degree-j][j];
710 return (Vtemp[degree][0]);
726 sign = old_sign =
SGN(VT[0][1]);
729 sign =
SGN(VT[i][1]);
730 if (sign != old_sign) n_crossings++;
750 time_type intercept_1, intercept_2, left_intercept, right_intercept;
765 abSquared = (a *
a) + (b * b);
770 distance[i] = a * VT[i][0] + b * VT[i][1] +
c;
771 if (distance[i] > 0.0) distance[i] = (distance[i] * distance[i]) / abSquared;
772 if (distance[i] < 0.0) distance[i] = -(distance[i] * distance[i]) / abSquared;
777 max_distance_above = max_distance_below = 0.0;
781 if (distance[i] < 0.0) max_distance_below =
MIN(max_distance_below, distance[i]);
782 if (distance[i] > 0.0) max_distance_above =
MAX(max_distance_above, distance[i]);
786 intercept_1 = -(c + max_distance_above)/a;
789 intercept_2 = -(c + max_distance_below)/a;
792 left_intercept =
MIN(intercept_1, intercept_2);
793 right_intercept =
MAX(intercept_1, intercept_2);
795 return 0.5 * (right_intercept-left_intercept) <
BEZIER_EPSILON ? 1 : 0;
808 return (YNM*VT[0][0] - (VT[
W_DEGREE][0] - VT[0][0])*VT[0][1]) / YNM;
843 t[0] = (w[0][0] + w[
W_DEGREE][0]) / 2.0;
858 left_count =
FindRoots(Left, left_t, depth+1);
859 right_count =
FindRoots(Right, right_t, depth+1);
862 for (i = 0; i < left_count; i++) t[i] = left_t[i];
863 for (i = 0; i < right_count; i++) t[i+left_count] = right_t[i];
866 return (left_count+right_count);
880 int i, j, k, m, n, ub, lb;
886 {1.0, 0.6, 0.3, 0.1},
887 {0.4, 0.6, 0.6, 0.4},
888 {0.1, 0.3, 0.6, 1.0}};
892 for (i = 0; i <=
DEGREE; i++)
897 for (i = 0; i <=
DEGREE - 1; i++)
898 d[i] = (VT[i+1] - VT[i]) * 3.0;
902 for (row = 0; row <=
DEGREE - 1; row++)
903 for (column = 0; column <=
DEGREE; column++)
904 cdTable[row][column] = d[row] * c[column];
916 for (k = 0; k <= n + m; k++)
920 for (i = lb; i <= ub; i++)
923 w[i+j][1] += cdTable[j][i] * z[j][i];
948 n_solutions =
FindRoots(w, t_candidate, 0);
957 dist = (P - VT[0]).mag_squared();
961 for (i = 0; i < n_solutions; i++)
964 new_dist = (P - p).mag_squared();
973 new_dist = (P - VT[
DEGREE]).mag_squared();