Skip to content

Commit

Permalink
Add the early stopping in _twin_spline_decompose
Browse files Browse the repository at this point in the history
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
  • Loading branch information
weihsinyeh committed Sep 15, 2024
1 parent 90129bb commit ad161ac
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions src/spline.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand Down

0 comments on commit ad161ac

Please sign in to comment.