mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-04 03:45:58 -05:00
Refactor PathFlattener code and add maxRecursion and tolerance arguments to constructor.
This commit is contained in:
parent
7d69ef1864
commit
1db4fb4064
1 changed files with 59 additions and 41 deletions
|
@ -16,28 +16,66 @@
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var PathFlattener = Base.extend({
|
var PathFlattener = Base.extend({
|
||||||
initialize: function(path, matrix) {
|
/**
|
||||||
this.curves = []; // The curve values as returned by getValues()
|
* Creates a path flattener for the given path.
|
||||||
this.parts = []; // The calculated, subdivided parts of the path
|
*
|
||||||
this.length = 0; // The total length of the path
|
* @param {Path} path the path to iterate over.
|
||||||
// Keep a current index from the part where we last where in
|
* @param {Matrix} [matrix] the matrix by which to transform the path's
|
||||||
// getParameterAt(), to optimise for iterator-like usage of flattener.
|
* coordinates without modifying the actual path.
|
||||||
this.index = 0;
|
* @param {Number} [maxRecursion=32] the maximum amount of recursion in
|
||||||
|
* curve subdivision when mapping offsets to curve parameters.
|
||||||
|
* @param {Number} [tolerance=0.25] the error tolerance at which the
|
||||||
|
* recursion is interrupted before the maximum number of iterations is
|
||||||
|
* reached.
|
||||||
|
* @return {PathFlattener} the newly created path flattener.
|
||||||
|
*/
|
||||||
|
initialize: function(path, matrix, maxRecursion, tolerance) {
|
||||||
|
if (!tolerance)
|
||||||
|
tolerance = 0.25;
|
||||||
|
|
||||||
// Instead of relying on path.curves, we only use segments here and
|
// Instead of relying on path.curves, we only use segments here and
|
||||||
// get the curve values from them.
|
// get the curve values from them.
|
||||||
|
var curves = [], // The curve values as returned by getValues()
|
||||||
// Now walk through all curves and compute the parts for each of them,
|
parts = [], // The calculated, subdivided parts of the path
|
||||||
// by recursively calling _computeParts().
|
length = 0, // The total length of the path
|
||||||
var segments = path._segments,
|
minDifference = 1 / (maxRecursion || 32),
|
||||||
|
segments = path._segments,
|
||||||
segment1 = segments[0],
|
segment1 = segments[0],
|
||||||
segment2,
|
segment2;
|
||||||
that = this;
|
|
||||||
|
|
||||||
|
// Iterate through all curves and compute the parts for each of them,
|
||||||
|
// by recursively calling computeParts().
|
||||||
function addCurve(segment1, segment2) {
|
function addCurve(segment1, segment2) {
|
||||||
var curve = Curve.getValues(segment1, segment2, matrix);
|
var curve = Curve.getValues(segment1, segment2, matrix);
|
||||||
that.curves.push(curve);
|
curves.push(curve);
|
||||||
that._computeParts(curve, segment1._index, 0, 1);
|
computeParts(curve, segment1._index, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeParts(curve, index, minT, maxT) {
|
||||||
|
// Check if the t-span is big enough for subdivision.
|
||||||
|
// We're not subdividing more than 32 times...
|
||||||
|
// After quite a bit of testing, a tolerance of 0.25 appears to be a
|
||||||
|
// good trade-off between speed and precision.
|
||||||
|
if ((maxT - minT) > 1 / 32 && !Curve.isFlatEnough(curve, 0.25)) {
|
||||||
|
var split = Curve.subdivide(curve),
|
||||||
|
halfT = (minT + maxT) / 2;
|
||||||
|
// Recursively subdivide and compute parts again.
|
||||||
|
computeParts(split[0], index, minT, halfT);
|
||||||
|
computeParts(split[1], index, halfT, maxT);
|
||||||
|
} else {
|
||||||
|
// Calculate distance between p1 and p2
|
||||||
|
var x = curve[6] - curve[0],
|
||||||
|
y = curve[7] - curve[1],
|
||||||
|
dist = Math.sqrt(x * x + y * y);
|
||||||
|
if (dist > /*#=*/Numerical.TOLERANCE) {
|
||||||
|
length += dist;
|
||||||
|
parts.push({
|
||||||
|
offset: length,
|
||||||
|
value: maxT,
|
||||||
|
index: index
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 1, l = segments.length; i < l; i++) {
|
for (var i = 1, l = segments.length; i < l; i++) {
|
||||||
|
@ -47,33 +85,13 @@ var PathFlattener = Base.extend({
|
||||||
}
|
}
|
||||||
if (path._closed)
|
if (path._closed)
|
||||||
addCurve(segment2, segments[0]);
|
addCurve(segment2, segments[0]);
|
||||||
},
|
|
||||||
|
|
||||||
_computeParts: function(curve, index, minT, maxT) {
|
this.curves = curves;
|
||||||
// Check if the t-span is big enough for subdivision.
|
this.parts = parts;
|
||||||
// We're not subdividing more than 32 times...
|
this.length = length;
|
||||||
// After quite a bit of testing, a tolerance of 0.25 appears to be a
|
// Keep a current index from the part where we last where in
|
||||||
// good trade-off between speed and precision.
|
// getParameterAt(), to optimise for iterator-like usage of flattener.
|
||||||
if ((maxT - minT) > 1 / 32 && !Curve.isFlatEnough(curve, 0.25)) {
|
this.index = 0;
|
||||||
var curves = Curve.subdivide(curve);
|
|
||||||
var halfT = (minT + maxT) / 2;
|
|
||||||
// Recursively subdive and compute parts again.
|
|
||||||
this._computeParts(curves[0], index, minT, halfT);
|
|
||||||
this._computeParts(curves[1], index, halfT, maxT);
|
|
||||||
} else {
|
|
||||||
// Calculate distance between p1 and p2
|
|
||||||
var x = curve[6] - curve[0],
|
|
||||||
y = curve[7] - curve[1],
|
|
||||||
dist = Math.sqrt(x * x + y * y);
|
|
||||||
if (dist > /*#=*/Numerical.TOLERANCE) {
|
|
||||||
this.length += dist;
|
|
||||||
this.parts.push({
|
|
||||||
offset: this.length,
|
|
||||||
value: maxT,
|
|
||||||
index: index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getParameterAt: function(offset) {
|
getParameterAt: function(offset) {
|
||||||
|
|
Loading…
Reference in a new issue