Correctly handle negative smooth() indices on open paths.

This commit is contained in:
Jürg Lehni 2016-01-11 20:21:27 +01:00
parent 86b9d04c43
commit 4c92c0739e
2 changed files with 19 additions and 8 deletions

View file

@ -2079,11 +2079,12 @@ var Path = PathItem.extend(/** @lends Path# */{
+ (_default && value instanceof Curve ? 1 : 0)
: _default;
// Handle negative values based on whether a path is open or not:
// Closed paths are wrapped around the end (allowing values to be
// negative), while open paths stay within the open range.
return index < 0 && closed
// Ranges on closed paths are allowed to wrapped around the
// beginning/end (e.g. start near the end, end near the beginning),
// while ranges on open paths stay within the path's open range.
return Numerical.clamp(index < 0 && closed
? index % length
: (Math.min(index, length - 1) % length + length) % length;
: index < 0 ? index + length : index, 0, length);
}
var opts = options || {},

View file

@ -63,7 +63,7 @@ var Numerical = new function() {
EPSILON = 1e-12,
MACHINE_EPSILON = 1.12e-16;
function clip(value, min, max) {
function clamp(value, min, max) {
return value < min ? min : value > max ? max : value;
}
@ -133,6 +133,16 @@ var Numerical = new function() {
return val >= -EPSILON && val <= EPSILON;
},
/**
* Returns a number whose value is clamped by the given range.
*
* @param {Number} value the value to be clamped
* @param {Number} min the lower boundary of the range
* @param {Number} max the upper boundary of the range
* @return {Number} a number in the range of [min, max]
*/
clamp: clamp,
/**
* Gauss-Legendre Numerical Integration.
*/
@ -254,10 +264,10 @@ var Numerical = new function() {
// We need to include EPSILON in the comparisons with min / max,
// as some solutions are ever so lightly out of bounds.
if (isFinite(x1) && (min == null || x1 > eMin && x1 < eMax))
roots[count++] = min == null ? x1 : clip(x1, min, max);
roots[count++] = min == null ? x1 : clamp(x1, min, max);
if (x2 !== x1
&& isFinite(x2) && (min == null || x2 > eMin && x2 < eMax))
roots[count++] = min == null ? x2 : clip(x2, min, max);
roots[count++] = min == null ? x2 : clamp(x2, min, max);
return count;
},
@ -349,7 +359,7 @@ var Numerical = new function() {
var count = Numerical.solveQuadratic(a, b1, c2, roots, min, max);
if (isFinite(x) && (count === 0 || x !== roots[count - 1])
&& (min == null || x > min - EPSILON && x < max + EPSILON))
roots[count++] = min == null ? x : clip(x, min, max);
roots[count++] = min == null ? x : clamp(x, min, max);
return count;
}
};