mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-06 04:42:15 -05:00
Move Curve evaluate() method to private scope.
This commit is contained in:
parent
da82116501
commit
9fe93d1434
1 changed files with 104 additions and 104 deletions
|
@ -518,109 +518,6 @@ statics: {
|
||||||
return values;
|
return values;
|
||||||
},
|
},
|
||||||
|
|
||||||
_evaluate: function(v, t, type, normalized) {
|
|
||||||
// Do not produce results if parameter is out of range or invalid.
|
|
||||||
if (t == null || t < 0 || t > 1)
|
|
||||||
return null;
|
|
||||||
var p1x = v[0], p1y = v[1],
|
|
||||||
c1x = v[2], c1y = v[3],
|
|
||||||
c2x = v[4], c2y = v[5],
|
|
||||||
p2x = v[6], p2y = v[7],
|
|
||||||
tolerance = /*#=*/Numerical.TOLERANCE,
|
|
||||||
x, y;
|
|
||||||
|
|
||||||
// Handle special case at beginning / end of curve
|
|
||||||
if (type === 0 && (t < tolerance || t > 1 - tolerance)) {
|
|
||||||
var isZero = t < tolerance;
|
|
||||||
x = isZero ? p1x : p2x;
|
|
||||||
y = isZero ? p1y : p2y;
|
|
||||||
} else {
|
|
||||||
// Calculate the polynomial coefficients.
|
|
||||||
var cx = 3 * (c1x - p1x),
|
|
||||||
bx = 3 * (c2x - c1x) - cx,
|
|
||||||
ax = p2x - p1x - cx - bx,
|
|
||||||
|
|
||||||
cy = 3 * (c1y - p1y),
|
|
||||||
by = 3 * (c2y - c1y) - cy,
|
|
||||||
ay = p2y - p1y - cy - by;
|
|
||||||
if (type === 0) {
|
|
||||||
// Calculate the curve point at parameter value t
|
|
||||||
x = ((ax * t + bx) * t + cx) * t + p1x;
|
|
||||||
y = ((ay * t + by) * t + cy) * t + p1y;
|
|
||||||
} else {
|
|
||||||
// 1: tangent, 1st derivative
|
|
||||||
// 2: normal, 1st derivative
|
|
||||||
// 3: curvature, 1st derivative & 2nd derivative
|
|
||||||
// Simply use the derivation of the bezier function for both
|
|
||||||
// the x and y coordinates:
|
|
||||||
// Prevent tangents and normals of length 0:
|
|
||||||
// http://stackoverflow.com/questions/10506868/
|
|
||||||
if (t < tolerance) {
|
|
||||||
x = cx;
|
|
||||||
y = cy;
|
|
||||||
} else if (t > 1 - tolerance) {
|
|
||||||
x = 3 * (p2x - c2x);
|
|
||||||
y = 3 * (p2y - c2y);
|
|
||||||
} else {
|
|
||||||
x = (3 * ax * t + 2 * bx) * t + cx;
|
|
||||||
y = (3 * ay * t + 2 * by) * t + cy;
|
|
||||||
}
|
|
||||||
if (normalized) {
|
|
||||||
// When the tangent at t is zero and we're at the beginning
|
|
||||||
// or the end, we can use the vector between the handles,
|
|
||||||
// but only when normalizing as its weighted length is 0.
|
|
||||||
if (x === 0 && y === 0
|
|
||||||
&& (t < tolerance || t > 1 - tolerance)) {
|
|
||||||
x = c2x - c1x;
|
|
||||||
y = c2y - c1y;
|
|
||||||
}
|
|
||||||
// Now normalize x & y
|
|
||||||
var len = Math.sqrt(x * x + y * y);
|
|
||||||
x /= len;
|
|
||||||
y /= len;
|
|
||||||
}
|
|
||||||
if (type === 3) {
|
|
||||||
// Calculate 2nd derivative, and curvature from there:
|
|
||||||
// http://cagd.cs.byu.edu/~557/text/ch2.pdf page#31
|
|
||||||
// k = |dx * d2y - dy * d2x| / (( dx^2 + dy^2 )^(3/2))
|
|
||||||
var x2 = 6 * ax * t + 2 * bx,
|
|
||||||
y2 = 6 * ay * t + 2 * by,
|
|
||||||
d = Math.pow(x * x + y * y, 3 / 2);
|
|
||||||
// For JS optimizations we always return a Point, although
|
|
||||||
// curvature is just a numeric value, stored in x:
|
|
||||||
x = d !== 0 ? (x * y2 - y * x2) / d : 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The normal is simply the rotated tangent:
|
|
||||||
return type === 2 ? new Point(y, -x) : new Point(x, y);
|
|
||||||
},
|
|
||||||
|
|
||||||
getPoint: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 0, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
getTangent: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 1, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
getWeightedTangent: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 1, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
getNormal: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 2, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
getWeightedNormal: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 2, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurvature: function(v, t) {
|
|
||||||
return Curve._evaluate(v, t, 3, false).x;
|
|
||||||
},
|
|
||||||
|
|
||||||
subdivide: function(v, t) {
|
subdivide: function(v, t) {
|
||||||
var p1x = v[0], p1y = v[1],
|
var p1x = v[0], p1y = v[1],
|
||||||
c1x = v[2], c1y = v[3],
|
c1x = v[2], c1y = v[3],
|
||||||
|
@ -1074,7 +971,7 @@ statics: {
|
||||||
* @return {Number} the curvature of the curve at the given offset
|
* @return {Number} the curvature of the curve at the given offset
|
||||||
*/
|
*/
|
||||||
}),
|
}),
|
||||||
new function() { // Scope for methods that require numerical integration
|
new function() { // Scope for methods that require private functions
|
||||||
|
|
||||||
function getLengthIntegrand(v) {
|
function getLengthIntegrand(v) {
|
||||||
// Calculate the coefficients of a Bezier derivative.
|
// Calculate the coefficients of a Bezier derivative.
|
||||||
|
@ -1107,6 +1004,85 @@ new function() { // Scope for methods that require numerical integration
|
||||||
return Math.max(2, Math.min(16, Math.ceil(Math.abs(b - a) * 32)));
|
return Math.max(2, Math.min(16, Math.ceil(Math.abs(b - a) * 32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function evaluate(v, t, type, normalized) {
|
||||||
|
// Do not produce results if parameter is out of range or invalid.
|
||||||
|
if (t == null || t < 0 || t > 1)
|
||||||
|
return null;
|
||||||
|
var p1x = v[0], p1y = v[1],
|
||||||
|
c1x = v[2], c1y = v[3],
|
||||||
|
c2x = v[4], c2y = v[5],
|
||||||
|
p2x = v[6], p2y = v[7],
|
||||||
|
tolerance = /*#=*/Numerical.TOLERANCE,
|
||||||
|
x, y;
|
||||||
|
|
||||||
|
// Handle special case at beginning / end of curve
|
||||||
|
if (type === 0 && (t < tolerance || t > 1 - tolerance)) {
|
||||||
|
var isZero = t < tolerance;
|
||||||
|
x = isZero ? p1x : p2x;
|
||||||
|
y = isZero ? p1y : p2y;
|
||||||
|
} else {
|
||||||
|
// Calculate the polynomial coefficients.
|
||||||
|
var cx = 3 * (c1x - p1x),
|
||||||
|
bx = 3 * (c2x - c1x) - cx,
|
||||||
|
ax = p2x - p1x - cx - bx,
|
||||||
|
|
||||||
|
cy = 3 * (c1y - p1y),
|
||||||
|
by = 3 * (c2y - c1y) - cy,
|
||||||
|
ay = p2y - p1y - cy - by;
|
||||||
|
if (type === 0) {
|
||||||
|
// Calculate the curve point at parameter value t
|
||||||
|
x = ((ax * t + bx) * t + cx) * t + p1x;
|
||||||
|
y = ((ay * t + by) * t + cy) * t + p1y;
|
||||||
|
} else {
|
||||||
|
// 1: tangent, 1st derivative
|
||||||
|
// 2: normal, 1st derivative
|
||||||
|
// 3: curvature, 1st derivative & 2nd derivative
|
||||||
|
// Simply use the derivation of the bezier function for both
|
||||||
|
// the x and y coordinates:
|
||||||
|
// Prevent tangents and normals of length 0:
|
||||||
|
// http://stackoverflow.com/questions/10506868/
|
||||||
|
if (t < tolerance) {
|
||||||
|
x = cx;
|
||||||
|
y = cy;
|
||||||
|
} else if (t > 1 - tolerance) {
|
||||||
|
x = 3 * (p2x - c2x);
|
||||||
|
y = 3 * (p2y - c2y);
|
||||||
|
} else {
|
||||||
|
x = (3 * ax * t + 2 * bx) * t + cx;
|
||||||
|
y = (3 * ay * t + 2 * by) * t + cy;
|
||||||
|
}
|
||||||
|
if (normalized) {
|
||||||
|
// When the tangent at t is zero and we're at the beginning
|
||||||
|
// or the end, we can use the vector between the handles,
|
||||||
|
// but only when normalizing as its weighted length is 0.
|
||||||
|
if (x === 0 && y === 0
|
||||||
|
&& (t < tolerance || t > 1 - tolerance)) {
|
||||||
|
x = c2x - c1x;
|
||||||
|
y = c2y - c1y;
|
||||||
|
}
|
||||||
|
// Now normalize x & y
|
||||||
|
var len = Math.sqrt(x * x + y * y);
|
||||||
|
x /= len;
|
||||||
|
y /= len;
|
||||||
|
}
|
||||||
|
if (type === 3) {
|
||||||
|
// Calculate 2nd derivative, and curvature from there:
|
||||||
|
// http://cagd.cs.byu.edu/~557/text/ch2.pdf page#31
|
||||||
|
// k = |dx * d2y - dy * d2x| / (( dx^2 + dy^2 )^(3/2))
|
||||||
|
var x2 = 6 * ax * t + 2 * bx,
|
||||||
|
y2 = 6 * ay * t + 2 * by,
|
||||||
|
d = Math.pow(x * x + y * y, 3 / 2);
|
||||||
|
// For JS optimizations we always return a Point, although
|
||||||
|
// curvature is just a numeric value, stored in x:
|
||||||
|
x = d !== 0 ? (x * y2 - y * x2) / d : 0;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The normal is simply the rotated tangent:
|
||||||
|
return type === 2 ? new Point(y, -x) : new Point(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statics: true,
|
statics: true,
|
||||||
|
|
||||||
|
@ -1173,6 +1149,30 @@ new function() { // Scope for methods that require numerical integration
|
||||||
// NOTE: guess is a negative value when not looking forward.
|
// NOTE: guess is a negative value when not looking forward.
|
||||||
return Numerical.findRoot(f, ds, start + guess, a, b, 16,
|
return Numerical.findRoot(f, ds, start + guess, a, b, 16,
|
||||||
tolerance);
|
tolerance);
|
||||||
|
},
|
||||||
|
|
||||||
|
getPoint: function(v, t) {
|
||||||
|
return evaluate(v, t, 0, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTangent: function(v, t) {
|
||||||
|
return evaluate(v, t, 1, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
getWeightedTangent: function(v, t) {
|
||||||
|
return evaluate(v, t, 1, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
getNormal: function(v, t) {
|
||||||
|
return evaluate(v, t, 2, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
getWeightedNormal: function(v, t) {
|
||||||
|
return evaluate(v, t, 2, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurvature: function(v, t) {
|
||||||
|
return evaluate(v, t, 3, false).x;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, new function() { // Scope for intersection using bezier fat-line clipping
|
}, new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
|
|
Loading…
Reference in a new issue