@@ -967,6 +967,7 @@ return( SplineMake3(from,to));
967967 bigreal bestError = 1e30 ;
968968 bigreal t ,error ,errorsum ,dist ;
969969 BasePoint prevcp ,nextcp ,coeff1 ,coeff2 ,coeff3 ;
970+ int last_best_j ;
970971 for (int k = 0 ; k < numberOfSolutions ; k ++ ) {
971972 nextcp .x = from -> me .x + ftlen * fromunit .x * abSolutions [k ][0 ];
972973 nextcp .y = from -> me .y + ftlen * fromunit .y * abSolutions [k ][0 ];
@@ -988,17 +989,21 @@ return( SplineMake3(from,to));
988989 }
989990 /* Now we calculate the error by determining the minimal quadratic distance to the mid points. */
990991 errorsum = 0.0 ;
992+ last_best_j = 0 ;
991993 for (int i = 0 ; i < cnt ; i ++ ) { /* Going through the mid points */
992- error = (mid [i ].p .x - approx [0 ].x )* (mid [i ].p .x - approx [0 ].x )
993- + (mid [i ].p .y - approx [0 ].y )* (mid [i ].p .y - approx [0 ].y );
994- /* Above we have just initialized the error and */
995- /* now we are going through the remaining 98 of */
996- /* 99 points on the approximate cubic bezier: */
997- for (int j = 1 ; j < 99 ; j ++ ) {
994+ error = 1e30 ;
995+ /* For this mid point, find the distance to the closest one of the */
996+ /* 99 points on the approximate cubic bezier. */
997+ /* To not favour approximations which trace the original multiple times */
998+ /* by going back and forth, only consider monotonic mappings. */
999+ /* I.e., start from the point that was closest to the previous mid point: */
1000+ for (int j = last_best_j ; j < 99 ; j ++ ) {
9981001 dist = (mid [i ].p .x - approx [j ].x )* (mid [i ].p .x - approx [j ].x )
9991002 + (mid [i ].p .y - approx [j ].y )* (mid [i ].p .y - approx [j ].y );
1000- if (dist < error )
1003+ if (dist < error ) {
10011004 error = dist ;
1005+ last_best_j = j ;
1006+ }
10021007 }
10031008 errorsum += error ;
10041009 if (errorsum > bestError )
0 commit comments