mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Move private getPeaks() to Curve.getPeaks()
It will be of use in the offsetting code as well.
This commit is contained in:
parent
7fc029d98b
commit
1f768c69d2
2 changed files with 40 additions and 28 deletions
|
@ -1681,6 +1681,43 @@ new function() { // Scope for methods that require private functions
|
||||||
|
|
||||||
getCurvature: function(v, t) {
|
getCurvature: function(v, t) {
|
||||||
return evaluate(v, t, 3, false).x;
|
return evaluate(v, t, 3, false).x;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the t values for the "peaks" of the curve. The peaks are
|
||||||
|
* calculated by finding the roots of the dot product of the first and
|
||||||
|
* second derivative.
|
||||||
|
*
|
||||||
|
* Peaks are locations sharing some qualities of curvature extrema but
|
||||||
|
* are cheaper to compute. They fulfill their purpose here quite well.
|
||||||
|
* See:
|
||||||
|
* http://math.stackexchange.com/questions/1954845/bezier-curvature-extrema
|
||||||
|
*
|
||||||
|
* @param {Number[]} v the curve values array
|
||||||
|
* @returns {Number[]} the roots of all found peaks
|
||||||
|
*/
|
||||||
|
getPeaks: function(v) {
|
||||||
|
var x0 = v[0], y0 = v[1],
|
||||||
|
x1 = v[2], y1 = v[3],
|
||||||
|
x2 = v[4], y2 = v[5],
|
||||||
|
x3 = v[6], y3 = v[7],
|
||||||
|
ax = -x0 + 3 * x1 - 3 * x2 + x3,
|
||||||
|
bx = 3 * x0 - 6 * x1 + 3 * x2,
|
||||||
|
cx = -3 * x0 + 3 * x1,
|
||||||
|
ay = -y0 + 3 * y1 - 3 * y2 + y3,
|
||||||
|
by = 3 * y0 - 6 * y1 + 3 * y2,
|
||||||
|
cy = -3 * y0 + 3 * y1,
|
||||||
|
tMin = /*#=*/Numerical.CURVETIME_EPSILON,
|
||||||
|
tMax = 1 - tMin,
|
||||||
|
roots = [];
|
||||||
|
Numerical.solveCubic(
|
||||||
|
9 * (ax * ax + ay * ay),
|
||||||
|
9 * (ax * bx + by * ay),
|
||||||
|
2 * (bx * bx + by * by) + 3 * (cx * ax + cy * ay),
|
||||||
|
(cx * bx + by * cy),
|
||||||
|
// Exclude 0 and 1 as we don't count them as peaks.
|
||||||
|
roots, tMin, tMax);
|
||||||
|
return roots.sort();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
},
|
},
|
||||||
|
|
|
@ -437,10 +437,10 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
var offsets = [];
|
var offsets = [];
|
||||||
|
|
||||||
function addOffsets(curve, end) {
|
function addOffsets(curve, end) {
|
||||||
// Find the largest offset of unambiguous direction on the curve by
|
// Find the largest offset of unambiguous direction on the curve,
|
||||||
// finding their inflections points and "peaks".
|
// taking their loops, cusps, inflections, and "peaks" into account.
|
||||||
var v = curve.getValues(),
|
var v = curve.getValues(),
|
||||||
roots = Curve.classify(v).roots || getPeaks(v),
|
roots = Curve.classify(v).roots || Curve.getPeaks(v),
|
||||||
count = roots.length,
|
count = roots.length,
|
||||||
t = end && count > 1 ? roots[count - 1]
|
t = end && count > 1 ? roots[count - 1]
|
||||||
: count > 0 ? roots[0]
|
: count > 0 ? roots[0]
|
||||||
|
@ -449,31 +449,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
offsets.push(Curve.getLength(v, end ? t : 0, end ? 1 : t) / 2);
|
offsets.push(Curve.getLength(v, end ? t : 0, end ? 1 : t) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peaks are locations sharing some qualities of curvature extrema but
|
|
||||||
// are cheaper to compute. They fulfill their purpose here quite well.
|
|
||||||
// See: http://math.stackexchange.com/questions/1954845/bezier-curvature-extrema
|
|
||||||
function getPeaks(v) {
|
|
||||||
var x0 = v[0], y0 = v[1],
|
|
||||||
x1 = v[2], y1 = v[3],
|
|
||||||
x2 = v[4], y2 = v[5],
|
|
||||||
x3 = v[6], y3 = v[7],
|
|
||||||
ax = -x0 + 3 * x1 - 3 * x2 + x3,
|
|
||||||
bx = 3 * x0 - 6 * x1 + 3 * x2,
|
|
||||||
cx = -3 * x0 + 3 * x1,
|
|
||||||
ay = -y0 + 3 * y1 - 3 * y2 + y3,
|
|
||||||
by = 3 * y0 - 6 * y1 + 3 * y2,
|
|
||||||
cy = -3 * y0 + 3 * y1,
|
|
||||||
roots = [];
|
|
||||||
Numerical.solveCubic(
|
|
||||||
9 * (ax * ax + ay * ay),
|
|
||||||
9 * (ax * bx + by * ay),
|
|
||||||
2 * (bx * bx + by * by) + 3 * (cx * ax + cy * ay),
|
|
||||||
(cx * bx + by * cy),
|
|
||||||
// Exclude 0 and 1 as we don't want to use them as peaks.
|
|
||||||
roots, tMin, tMax);
|
|
||||||
return roots.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInRange(angle, min, max) {
|
function isInRange(angle, min, max) {
|
||||||
return min < max
|
return min < max
|
||||||
? angle > min && angle < max
|
? angle > min && angle < max
|
||||||
|
|
Loading…
Reference in a new issue