Use smaller tolerances in winding code, to address edge cases.

Closes #559
This commit is contained in:
Jürg Lehni 2015-01-02 23:47:26 +01:00
parent 6359738618
commit 538eac6dc7
2 changed files with 16 additions and 11 deletions

View file

@ -705,9 +705,9 @@ statics: {
b = 2 * (v0 + v2) - 4 * v1,
c = v1 - v0,
count = Numerical.solveQuadratic(a, b, c, roots),
// Add some tolerance for good roots, as t = 0 / 1 are added
// separately anyhow, and we don't want joins to be added with
// radiuses in getStrokeBounds()
// Add some tolerance for good roots, as t = 0, 1 are added
// separately anyhow, and we don't want joins to be added with radii
// in getStrokeBounds()
tMin = /*#=*/Numerical.TOLERANCE,
tMax = 1 - tMin;
// Only add strokeWidth to bounds for points which lie within 0 < t < 1
@ -1134,10 +1134,7 @@ new function() { // Scope for methods that require numerical integration
parts[1], v1, curve2, curve1, locations, include,
t, uMax, tMinNew, tMaxNew, tDiff, !reverse, recursion);
}
} else if (Math.max(uMax - uMin, tMaxNew - tMinNew) < tolerance / 2) {
// NOTE: Not sure why we compare with half the tolerance here, but
// it appears to be needed to fix issue #568 (intersection is found
// twice): https://github.com/paperjs/paper.js/issues/568
} else if (Math.max(uMax - uMin, tMaxNew - tMinNew) < tolerance) {
// We have isolated the intersection with sufficient precision
var t1 = tMinNew + (tMaxNew - tMinNew) / 2,
t2 = uMin + (uMax - uMin) / 2;

View file

@ -224,8 +224,16 @@ PathItem.inject(new function() {
* with respect to a given set of monotone curves.
*/
function getWinding(point, curves, horizontal, testContains) {
var tolerance = /*#=*/Numerical.TOLERANCE,
tMax = 1 - tolerance,
// We need to use a smaller tolerance here than in the rest of the
// library when dealing with curve time parameters and coordinates, in
// order to get really precise values for winding tests. 1e-7 was
// determined through a lot of trial and error, and boolean-test suites.
// Further decreasing it produces new errors.
// The value of 1e-7 also solves issue #559:
// https://github.com/paperjs/paper.js/issues/559
var tolerance = 1e-7,
tMin = tolerance,
tMax = 1 - tMin,
x = point.x,
y = point.y,
windLeft = 0,
@ -293,8 +301,8 @@ PathItem.inject(new function() {
// curve merely touches the ray towards +-x direction, but
// proceeds to the same side of the ray. This essentially is
// not a crossing.
if (abs(slope) < tolerance && !Curve.isLinear(values)
|| t < tolerance && slope * Curve.evaluate(
if (Numerical.isZero(slope) && !Curve.isLinear(values)
|| t < tMin && slope * Curve.evaluate(
curve.previous.values, t, 1).y < 0) {
if (testContains && x0 >= xBefore && x0 <= xAfter) {
++windLeft;