Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve spline decomposition #2

Closed
jserv opened this issue Jul 17, 2024 · 4 comments
Closed

Improve spline decomposition #2

jserv opened this issue Jul 17, 2024 · 4 comments
Assignees

Comments

@jserv
Copy link
Contributor

jserv commented Jul 17, 2024

The usual method to convert a spline into a sequence of line segments is to split the spline in half using de Casteljau's algorithm recursively until the spline can be approximated by a straight line within a defined tolerance. The commit 6d85b42 has already changed the original recursion to an iterative method, avoiding unbounded recursion. Four levels of recursion will consume more than 64 coordinates' worth of space, which can easily overflow the stack of a tiny machine. However, as Keith mentioned in Slightly Better Iterative Spline Decomposition, it is possible to make the overall computational cost lower than a straightforward binary decomposition, and no recursion is required.

See also: Decomposing Splines Without Recursion

marvin0102 added a commit to marvin0102/mado that referenced this issue Jul 18, 2024
# 這是第一個提交說明:

Fix the incorrect rendering of PNG file

The red green blue permutations of twin and png are inconsistent.
Reverse the RGB premutation of png to BGR to make them consistent.

# 這是提交說明 sysprog21#2:

Fix the incorrect rendering of PNG files

Fix the RGB rendering of PNG files and pass the tests of color formats include
RGB, RGBA, PALETTE and GRAY.
marvin0102 added a commit to marvin0102/mado that referenced this issue Jul 18, 2024
# 這是第一個提交說明:

Fix the incorrect rendering of PNG file

The red green blue permutations of twin and png are inconsistent.
Reverse the RGB premutation of png to BGR to make them consistent.

# 這是提交說明 sysprog21#2:

Fix the incorrect rendering of PNG files

Fix the RGB rendering of PNG files and pass the tests of color formats include
RGB, RGBA, PALETTE and GRAY.
@jserv
Copy link
Contributor Author

jserv commented Jul 23, 2024

The font-edit is not only useful for observing how font rendering works but also serves as a testbed for evaluating the enhancement of iterative spline decomposition, where you can operate with floating point arithmetic instead of fixed-point arithmetic.

font-edit

@jouae
Copy link
Collaborator

jouae commented Jul 27, 2024

Here are two books that might be helpful:

A Primer on Bézier Curves
This book gives some interactive content can visually aid in understanding the significance of parameters.

Computer Aided Geometric Design
Discussing curve interpolation with rigorous mathematical exposition.

In the second book 10.6 Error Bounds,

We can assure that the approximation error will be less than a specified tolerance $\epsilon$ by using $m$ line segments whose endpoints are evenly spaced in $x$, where $m\geq \sqrt{\frac{L}{8\epsilon}}(x_1-x_0)$

weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 8, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

See https://keithp.com/blogs/more-iterative-splines/ for details.
See also: sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 8, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

See https://keithp.com/blogs/more-iterative-splines/ for details.
See also: sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 8, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 18, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 18, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 18, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Aug 18, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Sep 7, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Sep 15, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Sep 15, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Sep 15, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Sep 17, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
@jouae
Copy link
Collaborator

jouae commented Sep 18, 2024

Another feasible interpolation method is called the Euler spiral. According to @weihsinyeh's notes, the Google team adopted the Euler spiral in their paper titled "GPU-friendly Stroke Expansion," published in the Proceedings of the ACM on Computer Graphics and Interactive Techniques in 2024.

Raphael Linus Levien's work, From Spiral to Spline: Optimal Techniques in Interactive Curve Design, provides a detailed description of the characteristics of the curve, covering both its physical and mathematical aspects, as well as its application in font rendering.

weihsinyeh added a commit to weihsinyeh/mado that referenced this issue Nov 2, 2024
This commit focuses on decomposing a spline into fewer segments by
finding an optimal value of t that meets our target tolerance for
flatness while ensuring it is at least as large as the maximum distance
from the line segment connecting the starting and ending points of the
original curve.

The approach employs the bisection method to determine the value of t.
The idea behind this method is based on the properties of curves. By
choosing the point of maximum curvature as the junction between two line
segments during curve fitting, we ensure that the curvature of all
points on both segments is less than the maximum curvature of the
original curve. This strategy guarantees that the two line segments fit
the original curve as well as possible.

Additionally, the properties of these two segments are such that the
slope of the tangent line at all points in one segment is relatively
positive compared to the slope of the line connecting the starting and
ending points of the original curve, while the slope in the other
line segment is relatively negative. Consequently, the point where the
tangent line's slope is zero relative to the connecting line results in
the maximum distance.

This distance is recorded to ensure we maximize it as much as possible.
Although this approach requires more computation to decompose the
spline into fewer segments, the extra effort is justified for improved
fit.

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

See https://keithp.com/blogs/more-iterative-splines/ for details.
Close sysprog21#2
@jserv
Copy link
Contributor Author

jserv commented Nov 4, 2024

Close via 7e25ecd

@jserv jserv closed this as completed Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants