From ad161acdd3492a71a42a26fb4ab5fca5d0c3ca09 Mon Sep 17 00:00:00 2001 From: Wei-Hsin Yeh Date: Sun, 15 Sep 2024 17:08:28 +0800 Subject: [PATCH] Add the early stopping in _twin_spline_decompose Take the right half of the spline as another standard when finding the optimal t. Because if the right half of the spline is also within the tolerance, the right half of the spline will be the last curve segment. Thus, in this case, there is no need to find better t, which aims to prevent more line segments from being generated in the future. I have modified the implementation of font-edit to use fixed-point arithmetic and used it as the evaluation testbed to do experiments as follows: original - Average number of _de_casteljau calls per point: 1.99 original - Average points per character: 18.89 flexibly update - Average number of _de_casteljau calls per point: 4.53 flexibly update - Average points per character: 16.30 flexibly update (early stopping)- Average number of _de_casteljau calls per point: 4.23 flexibly update (early stopping)- Average points per character: 16.18 --- src/spline.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/spline.c b/src/spline.c index 3047f8c..b8ad347 100644 --- a/src/spline.c +++ b/src/spline.c @@ -97,7 +97,7 @@ static void _twin_spline_decompose(twin_path_t *path, while (!is_flat(spline, tolerance_squared)) { twin_dfixed_t hi = TWIN_SFIXED_ONE * TWIN_SFIXED_ONE, lo = 0, - t_optimal = 0, t, max_distance = 0, distance; + t_optimal = 0, t, max_distance = 0, left_dist, right_dist; twin_spline_t left, right; while (true) { @@ -107,14 +107,15 @@ static void _twin_spline_decompose(twin_path_t *path, _de_casteljau(spline, t, &left, &right); - distance = _twin_spline_distance_squared(&left); - if (distance < max_distance) - break; + left_dist = _twin_spline_distance_squared(&left); + right_dist = _twin_spline_distance_squared(&right); /* The left segment is close enough to fit the original spline. */ - if (distance <= tolerance_squared) { - max_distance = distance; + if (left_dist <= tolerance_squared) { + max_distance = left_dist; t_optimal = t; + if (right_dist <= tolerance_squared) + break; /* * Try to find a better point such that the line segment * connecting it to the previous point can fit the spline, while