mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
513bd1da67
4 changed files with 49 additions and 26 deletions
2
lib/bootstrap.js
vendored
2
lib/bootstrap.js
vendored
|
@ -166,7 +166,7 @@ var Base = this.Base = new function() {
|
||||||
|
|
||||||
function each(iter, bind, asArray) {
|
function each(iter, bind, asArray) {
|
||||||
try {
|
try {
|
||||||
(asArray || asArray == undefined && isArray(this) ? forEach : forIn)
|
(asArray || asArray === undefined && isArray(this) ? forEach : forIn)
|
||||||
.call(this, iterator(iter), bind = bind || this);
|
.call(this, iterator(iter), bind = bind || this);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e !== Base.stop) throw e;
|
if (e !== Base.stop) throw e;
|
||||||
|
|
|
@ -171,9 +171,10 @@ var Curve = this.Curve = Base.extend({
|
||||||
&& this._segment2._handleIn.isZero();
|
&& this._segment2._handleIn.isZero();
|
||||||
},
|
},
|
||||||
|
|
||||||
getParameter: function(length) {
|
// TODO: Port support for start parameter back to Scriptographer
|
||||||
|
getParameter: function(length, start) {
|
||||||
var args = this.getCurveValues();
|
var args = this.getCurveValues();
|
||||||
args.push(length)
|
args.push(length, start !== undefined ? start : length < 0 ? 1 : 0);
|
||||||
return Curve.getParameter.apply(Curve, args);
|
return Curve.getParameter.apply(Curve, args);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -309,15 +310,15 @@ var Curve = this.Curve = Base.extend({
|
||||||
|
|
||||||
statics: {
|
statics: {
|
||||||
getLength: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, a, b) {
|
getLength: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, a, b) {
|
||||||
if (a == undefined)
|
if (a === undefined)
|
||||||
a = 0;
|
a = 0;
|
||||||
if (b == undefined)
|
if (b === undefined)
|
||||||
b = 1;
|
b = 1;
|
||||||
if (p1x == c1x && p1y == c1y && p2x == c2x && p2y == c2y) {
|
if (p1x == c1x && p1y == c1y && p2x == c2x && p2y == c2y) {
|
||||||
// Straight line
|
// Straight line
|
||||||
var dx = p2x - p1x,
|
var dx = p2x - p1x,
|
||||||
dy = p2y - p1y;
|
dy = p2y - p1y;
|
||||||
return Math.sqrt(dx * dx + dy * dy) * (b - a);
|
return (b - a) * Math.sqrt(dx * dx + dy * dy);
|
||||||
}
|
}
|
||||||
var ds = getLengthIntegrand(
|
var ds = getLengthIntegrand(
|
||||||
p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
|
p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
|
||||||
|
@ -325,33 +326,55 @@ var Curve = this.Curve = Base.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
getParameter: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y,
|
getParameter: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y,
|
||||||
length) {
|
length, start) {
|
||||||
if (length <= 0)
|
if (length == 0) {
|
||||||
return 0;
|
return start;
|
||||||
|
}
|
||||||
if (p1x == c1x && p1y == c1y && p2x == c2x && p2y == c2y) {
|
if (p1x == c1x && p1y == c1y && p2x == c2x && p2y == c2y) {
|
||||||
// Straight line, calculate directly
|
// Straight line, calculate directly
|
||||||
// t = length / lineLength:
|
// t = length / lineLength:
|
||||||
var dx = p2x - p1x,
|
var dx = p2x - p1x,
|
||||||
dy = p2y - p1y;
|
dy = p2y - p1y;
|
||||||
return Math.min(length / Math.sqrt(dx * dx + dy * dy), 1);
|
return Math.max(Math.min(start
|
||||||
|
+ length / Math.sqrt(dx * dx + dy * dy), 0, 1));
|
||||||
}
|
}
|
||||||
var ds = getLengthIntegrand(
|
|
||||||
p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
|
|
||||||
// Use integrand both to calculate total length and part lengths
|
|
||||||
// in f(t) below.
|
|
||||||
var bezierLength = Numerical.integrate(ds, 0, 1, 8);
|
|
||||||
if (length >= bezierLength)
|
|
||||||
return 1;
|
|
||||||
// Let's use the Van Wijngaarden–Dekker–Brent Method to find
|
// Let's use the Van Wijngaarden–Dekker–Brent Method to find
|
||||||
// solutions more reliably than with False Position Method.
|
// solutions more reliably than with False Position Method.
|
||||||
function f(t) {
|
// The precision of 5 iterations seems enough for this
|
||||||
// The precision of 5 iterations seems enough for this
|
var forward = length > 0,
|
||||||
return length - Numerical.integrate(ds, 0, t, 5);
|
// Use integrand to calculate both range length and part
|
||||||
|
// lengths in f(t) below.
|
||||||
|
ds = getLengthIntegrand(
|
||||||
|
p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y),
|
||||||
|
a, b, f;
|
||||||
|
// See if we're going forward or backward, and handle cases
|
||||||
|
// differently
|
||||||
|
if (forward) { // Normal way
|
||||||
|
a = start;
|
||||||
|
b = 1;
|
||||||
|
// We're moving b to the right to find root for length
|
||||||
|
f = function(t) {
|
||||||
|
return length - Numerical.integrate(ds, a, t, 5);
|
||||||
|
}
|
||||||
|
} else { // Going backwards
|
||||||
|
a = 0;
|
||||||
|
b = start;
|
||||||
|
length = -length;
|
||||||
|
// We're moving a to the left to find root for length
|
||||||
|
f = function(t) {
|
||||||
|
return length - Numerical.integrate(ds, t, b, 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Use length / bezierLength for an initial guess for b, to
|
var rangeLength = Numerical.integrate(ds, a, b, 8);
|
||||||
|
if (length >= rangeLength)
|
||||||
|
return forward ? b : a;
|
||||||
|
// Use length / rangeLength for an initial guess for t, to
|
||||||
// bring us closer:
|
// bring us closer:
|
||||||
return Numerical.findRoot(f, 0, length / bezierLength,
|
var guess = length / rangeLength;
|
||||||
Numerical.TOLERANCE);
|
return Numerical.findRoot(f,
|
||||||
|
forward ? a : b - guess, // a
|
||||||
|
forward ? a + guess : b, // b
|
||||||
|
16, Numerical.TOLERANCE);
|
||||||
},
|
},
|
||||||
|
|
||||||
subdivide: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
|
subdivide: function(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ var Path = this.Path = PathItem.extend({
|
||||||
if (segment._path)
|
if (segment._path)
|
||||||
segment = new Segment(segment);
|
segment = new Segment(segment);
|
||||||
segment._path = this;
|
segment._path = this;
|
||||||
if (index == undefined) {
|
if (index === undefined) {
|
||||||
this._segments.push(segment);
|
this._segments.push(segment);
|
||||||
} else {
|
} else {
|
||||||
this._segments.splice(index, 0, segment);
|
this._segments.splice(index, 0, segment);
|
||||||
|
|
|
@ -59,13 +59,13 @@ var Numerical = new function() {
|
||||||
* Van Wijngaarden–Dekker–Brent method for root finding, implementation
|
* Van Wijngaarden–Dekker–Brent method for root finding, implementation
|
||||||
* based on Numerical Recipes in C
|
* based on Numerical Recipes in C
|
||||||
*/
|
*/
|
||||||
findRoot: function(f, a, b, tol) {
|
findRoot: function(f, a, b, n, tol) {
|
||||||
var c = b, d = 0, e = 0,
|
var c = b, d = 0, e = 0,
|
||||||
fa = f(a),
|
fa = f(a),
|
||||||
fb = f(b),
|
fb = f(b),
|
||||||
fc = fb;
|
fc = fb;
|
||||||
|
|
||||||
for (var i = 1; i <= 64; i++) {
|
for (var i = 0; i < n; i++) {
|
||||||
if ((fb > 0 && fc > 0) || (fb < 0 && fc < 0)) {
|
if ((fb > 0 && fc > 0) || (fb < 0 && fc < 0)) {
|
||||||
c = a;
|
c = a;
|
||||||
fc = fa;
|
fc = fa;
|
||||||
|
|
Loading…
Reference in a new issue