solveCubic needs fixes (or perhaps its algorithm replaced)
See original GitHub issueI’ve been investigating why Robofab’s correctDirection fails to correctly set the direction of some contours, and I think I found one possible cause: the method uses FontTools’ PointInsidePen which in turn relies on solveCubic. What I found in my exploration is that in some cases solveCubic
does not return the correct list roots. Observe these two examples:
from fontTools.misc.bezierTools import solveCubic
print solveCubic(-10.0, -9.0, 48.0, -29.0) #1
print solveCubic(-9.875, -9.0, 47.625, -28.75) #2
Equation 1: -10x³ - 9x² + 48x - 29 = 0
This equation has two solutions, x = 1
and x = -29 / 10
.
The output of solveCubic
is [-2.9, 0.9999999999999993, 1.000000000000001]
.
Equation 2: -9.875x³ - 9x² + 47.625x - 28.75 = 0
This equation also has two solutions, x = 1
and x = -230 / 79
.
The output of solveCubic
is [-2.911392405063291]
.
While the rounding error in the results of the first equation is expected, the missing solution(s) in the output of the second equation is a real problem.
There are several methods for solving cubic functions. I’ve experimented with the method detailed on this page. It yielded several more correct path directions, but wasn’t the silver bullet I was hoping for. Perhaps it’s still not the best algorithm, or there are possibly other bugs in the code path chain.
It’d be great if you guys could have a look at this. Thanks!
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:27 (21 by maintainers)
Top GitHub Comments
We should remove the P() abstraction from that and add the pen into fonttools.
Curve area is really simple. Here’s a standalone area-pen: