mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Unify naming of bezier coordinates in internal calculations.
This commit is contained in:
parent
6e96fd6be5
commit
4e215b0eab
1 changed files with 125 additions and 125 deletions
|
@ -616,27 +616,27 @@ statics: /** @lends Curve */{
|
|||
},
|
||||
|
||||
subdivide: function(v, t) {
|
||||
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];
|
||||
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];
|
||||
if (t === undefined)
|
||||
t = 0.5;
|
||||
// Triangle computation, with loops unrolled.
|
||||
var u = 1 - t,
|
||||
// Interpolate from 4 to 3 points
|
||||
p3x = u * p1x + t * c1x, p3y = u * p1y + t * c1y,
|
||||
p4x = u * c1x + t * c2x, p4y = u * c1y + t * c2y,
|
||||
p5x = u * c2x + t * p2x, p5y = u * c2y + t * p2y,
|
||||
x4 = u * x0 + t * x1, y4 = u * y0 + t * y1,
|
||||
x5 = u * x1 + t * x2, y5 = u * y1 + t * y2,
|
||||
x6 = u * x2 + t * x3, y6 = u * y2 + t * y3,
|
||||
// Interpolate from 3 to 2 points
|
||||
p6x = u * p3x + t * p4x, p6y = u * p3y + t * p4y,
|
||||
p7x = u * p4x + t * p5x, p7y = u * p4y + t * p5y,
|
||||
x7 = u * x4 + t * x5, y7 = u * y4 + t * y5,
|
||||
x8 = u * x5 + t * x6, y8 = u * y5 + t * y6,
|
||||
// Interpolate from 2 points to 1 point
|
||||
p8x = u * p6x + t * p7x, p8y = u * p6y + t * p7y;
|
||||
x9 = u * x7 + t * x8, y9 = u * y7 + t * y8;
|
||||
// We now have all the values we need to build the sub-curves:
|
||||
return [
|
||||
[p1x, p1y, p3x, p3y, p6x, p6y, p8x, p8y], // left
|
||||
[p8x, p8y, p7x, p7y, p5x, p5y, p2x, p2y] // right
|
||||
[x0, y0, x4, y4, x7, y7, x9, y9], // left
|
||||
[x9, y9, x8, y8, x6, y6, x3, y3] // right
|
||||
];
|
||||
},
|
||||
|
||||
|
@ -691,21 +691,21 @@ statics: /** @lends Curve */{
|
|||
return curves;
|
||||
},
|
||||
|
||||
// Converts from the point coordinates (p1, c1, c2, p2) for one axis to
|
||||
// Converts from the point coordinates (p0, p1, p2, p3) for one axis to
|
||||
// the polynomial coefficients and solves the polynomial for val
|
||||
solveCubic: function (v, coord, val, roots, min, max) {
|
||||
var p1 = v[coord],
|
||||
c1 = v[coord + 2],
|
||||
c2 = v[coord + 4],
|
||||
p2 = v[coord + 6],
|
||||
var v0 = v[coord],
|
||||
v1 = v[coord + 2],
|
||||
v2 = v[coord + 4],
|
||||
v3 = v[coord + 6],
|
||||
res = 0;
|
||||
// If val is outside the curve values, no solution is possible.
|
||||
if ( !(p1 < val && p2 < val && c1 < val && c2 < val ||
|
||||
p1 > val && p2 > val && c1 > val && c2 > val)) {
|
||||
var c = 3 * (c1 - p1),
|
||||
b = 3 * (c2 - c1) - c,
|
||||
a = p2 - p1 - c - b;
|
||||
res = Numerical.solveCubic(a, b, c, p1 - val, roots, min, max);
|
||||
if ( !(v0 < val && v3 < val && v1 < val && v2 < val ||
|
||||
v0 > val && v3 > val && v1 > val && v2 > val)) {
|
||||
var c = 3 * (v1 - v0),
|
||||
b = 3 * (v2 - v1) - c,
|
||||
a = v3 - v0 - c - b;
|
||||
res = Numerical.solveCubic(a, b, c, v0 - val, roots, min, max);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
@ -713,12 +713,12 @@ statics: /** @lends Curve */{
|
|||
getTimeOf: function(v, point) {
|
||||
// Before solving cubics, compare the beginning and end of the curve
|
||||
// with zero epsilon:
|
||||
var p1 = new Point(v[0], v[1]),
|
||||
p2 = new Point(v[6], v[7]),
|
||||
var p0 = new Point(v[0], v[1]),
|
||||
p3 = new Point(v[6], v[7]),
|
||||
epsilon = /*#=*/Numerical.EPSILON,
|
||||
geomEpsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
|
||||
t = point.isClose(p1, epsilon) ? 0
|
||||
: point.isClose(p2, epsilon) ? 1
|
||||
t = point.isClose(p0, epsilon) ? 0
|
||||
: point.isClose(p3, epsilon) ? 1
|
||||
: null;
|
||||
if (t === null) {
|
||||
// Solve the cubic for both x- and y-coordinates and consider all
|
||||
|
@ -736,27 +736,27 @@ statics: /** @lends Curve */{
|
|||
}
|
||||
// Since we're comparing with geometric epsilon for any other t along
|
||||
// the curve, do so as well now for the beginning and end of the curve.
|
||||
return point.isClose(p1, geomEpsilon) ? 0
|
||||
: point.isClose(p2, geomEpsilon) ? 1
|
||||
return point.isClose(p0, geomEpsilon) ? 0
|
||||
: point.isClose(p3, geomEpsilon) ? 1
|
||||
: null;
|
||||
},
|
||||
|
||||
getNearestTime: function(v, point) {
|
||||
if (Curve.isStraight(v)) {
|
||||
var p1x = v[0], p1y = v[1],
|
||||
p2x = v[6], p2y = v[7],
|
||||
vx = p2x - p1x, vy = p2y - p1y,
|
||||
var x0 = v[0], y0 = v[1],
|
||||
x3 = v[6], y3 = v[7],
|
||||
vx = x3 - x0, vy = y3 - y0,
|
||||
det = vx * vx + vy * vy;
|
||||
// Avoid divisions by zero.
|
||||
if (det === 0)
|
||||
return 0;
|
||||
// Project the point onto the line and calculate its linear
|
||||
// parameter u along the line: u = (point - p1).dot(v) / v.dot(v)
|
||||
var u = ((point.x - p1x) * vx + (point.y - p1y) * vy) / det;
|
||||
var u = ((point.x - x0) * vx + (point.y - y0) * vy) / det;
|
||||
return u < /*#=*/Numerical.EPSILON ? 0
|
||||
: u > /*#=*/(1 - Numerical.EPSILON) ? 1
|
||||
: Curve.getTimeOf(v,
|
||||
new Point(p1x + u * vx, p1y + u * vy));
|
||||
new Point(x0 + u * vx, y0 + u * vy));
|
||||
}
|
||||
|
||||
var count = 100,
|
||||
|
@ -818,27 +818,27 @@ statics: /** @lends Curve */{
|
|||
isFlatEnough: function(v, flatness) {
|
||||
// Thanks to Kaspar Fischer and Roger Willcocks for the following:
|
||||
// http://hcklbrrfnn.files.wordpress.com/2012/08/bez.pdf
|
||||
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],
|
||||
ux = 3 * c1x - 2 * p1x - p2x,
|
||||
uy = 3 * c1y - 2 * p1y - p2y,
|
||||
vx = 3 * c2x - 2 * p2x - p1x,
|
||||
vy = 3 * c2y - 2 * p2y - p1y;
|
||||
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],
|
||||
ux = 3 * x1 - 2 * x0 - x3,
|
||||
uy = 3 * y1 - 2 * y0 - y3,
|
||||
vx = 3 * x2 - 2 * x3 - x0,
|
||||
vy = 3 * y2 - 2 * y3 - y0;
|
||||
return Math.max(ux * ux, vx * vx) + Math.max(uy * uy, vy * vy)
|
||||
<= 16 * flatness * flatness;
|
||||
},
|
||||
|
||||
getArea: function(v) {
|
||||
// http://objectmix.com/graphics/133553-area-closed-bezier-curve.html
|
||||
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];
|
||||
return 3 * ((p2y - p1y) * (c1x + c2x) - (p2x - p1x) * (c1y + c2y)
|
||||
+ c1y * (p1x - c2x) - c1x * (p1y - c2y)
|
||||
+ p2y * (c2x + p1x / 3) - p2x * (c2y + p1y / 3)) / 20;
|
||||
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];
|
||||
return 3 * ((y3 - y0) * (x1 + x2) - (x3 - x0) * (y1 + y2)
|
||||
+ y1 * (x0 - x2) - x1 * (y0 - y2)
|
||||
+ y3 * (x2 + x0 / 3) - x3 * (y2 + y0 / 3)) / 20;
|
||||
},
|
||||
|
||||
getBounds: function(v) {
|
||||
|
@ -1007,11 +1007,11 @@ statics: /** @lends Curve */{
|
|||
|
||||
// Produce the static version that handles a curve values array.
|
||||
this.statics[name] = function(v) {
|
||||
var p1x = v[0], p1y = v[1],
|
||||
p2x = v[6], p2y = v[7];
|
||||
return test(new Line(p1x, p1y, p2x, p2y),
|
||||
new Point(v[2] - p1x, v[3] - p1y),
|
||||
new Point(v[4] - p2x, v[5] - p2y));
|
||||
var x0 = v[0], y0 = v[1],
|
||||
x3 = v[6], y3 = v[7];
|
||||
return test(new Line(x0, y0, x3, y3),
|
||||
new Point(v[2] - x0, v[3] - y0),
|
||||
new Point(v[4] - x3, v[5] - y3));
|
||||
};
|
||||
}, /** @lends Curve# */{
|
||||
statics: {}, // Filled in the Base.each loop above.
|
||||
|
@ -1394,18 +1394,18 @@ new function() { // Scope for methods that require private functions
|
|||
|
||||
function getLengthIntegrand(v) {
|
||||
// Calculate the coefficients of a Bezier derivative.
|
||||
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],
|
||||
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 = 9 * (c1x - c2x) + 3 * (p2x - p1x),
|
||||
bx = 6 * (p1x + c2x) - 12 * c1x,
|
||||
cx = 3 * (c1x - p1x),
|
||||
ax = 9 * (x1 - x2) + 3 * (x3 - x0),
|
||||
bx = 6 * (x0 + x2) - 12 * x1,
|
||||
cx = 3 * (x1 - x0),
|
||||
|
||||
ay = 9 * (c1y - c2y) + 3 * (p2y - p1y),
|
||||
by = 6 * (p1y + c2y) - 12 * c1y,
|
||||
cy = 3 * (c1y - p1y);
|
||||
ay = 9 * (y1 - y2) + 3 * (y3 - y0),
|
||||
by = 6 * (y0 + y2) - 12 * y1,
|
||||
cy = 3 * (y1 - y0);
|
||||
|
||||
return function(t) {
|
||||
// Calculate quadratic equations of derivatives for x and y
|
||||
|
@ -1427,38 +1427,38 @@ new function() { // Scope for methods that require private functions
|
|||
// 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],
|
||||
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],
|
||||
isZero = Numerical.isZero;
|
||||
// If the curve handles are almost zero, reset the control points to the
|
||||
// anchors.
|
||||
if (isZero(c1x - p1x) && isZero(c1y - p1y)) {
|
||||
c1x = p1x;
|
||||
c1y = p1y;
|
||||
if (isZero(x1 - x0) && isZero(y1 - y0)) {
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
}
|
||||
if (isZero(c2x - p2x) && isZero(c2y - p2y)) {
|
||||
c2x = p2x;
|
||||
c2y = p2y;
|
||||
if (isZero(x2 - x3) && isZero(y2 - y3)) {
|
||||
x2 = x3;
|
||||
y2 = y3;
|
||||
}
|
||||
// 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,
|
||||
var cx = 3 * (x1 - x0),
|
||||
bx = 3 * (x2 - x1) - cx,
|
||||
ax = x3 - x0 - cx - bx,
|
||||
cy = 3 * (y1 - y0),
|
||||
by = 3 * (y2 - y1) - cy,
|
||||
ay = y3 - y0 - cy - by,
|
||||
x, y;
|
||||
if (type === 0) {
|
||||
// type === 0: getPoint()
|
||||
// Calculate the curve point at parameter value t
|
||||
// Use special handling at t === 0 / 1, to avoid imprecisions.
|
||||
// See #960
|
||||
x = t === 0 ? p1x : t === 1 ? p2x
|
||||
: ((ax * t + bx) * t + cx) * t + p1x;
|
||||
y = t === 0 ? p1y : t === 1 ? p2y
|
||||
: ((ay * t + by) * t + cy) * t + p1y;
|
||||
x = t === 0 ? x0 : t === 1 ? x3
|
||||
: ((ax * t + bx) * t + cx) * t + x0;
|
||||
y = t === 0 ? y0 : t === 1 ? y3
|
||||
: ((ay * t + by) * t + cy) * t + y0;
|
||||
} else {
|
||||
// type === 1: getTangent()
|
||||
// type === 2: getNormal()
|
||||
|
@ -1476,8 +1476,8 @@ new function() { // Scope for methods that require private functions
|
|||
x = cx;
|
||||
y = cy;
|
||||
} else if (t > tMax) {
|
||||
x = 3 * (p2x - c2x);
|
||||
y = 3 * (p2y - c2y);
|
||||
x = 3 * (x3 - x2);
|
||||
y = 3 * (y3 - y2);
|
||||
} else {
|
||||
x = (3 * ax * t + 2 * bx) * t + cx;
|
||||
y = (3 * ay * t + 2 * by) * t + cy;
|
||||
|
@ -1487,8 +1487,8 @@ new function() { // Scope for methods that require private functions
|
|||
// 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 < tMin || t > tMax)) {
|
||||
x = c2x - c1x;
|
||||
y = c2y - c1y;
|
||||
x = x2 - x1;
|
||||
y = y2 - y1;
|
||||
}
|
||||
// Now normalize x & y
|
||||
var len = Math.sqrt(x * x + y * y);
|
||||
|
@ -1532,15 +1532,15 @@ new function() { // Scope for methods that require private functions
|
|||
// considered if they are within 0..1. If the roots are outside,
|
||||
// then we degrade the type of curve down to an 'arch'.
|
||||
|
||||
var x1 = v[0], y1 = v[1],
|
||||
x2 = v[2], y2 = v[3],
|
||||
x3 = v[4], y3 = v[5],
|
||||
x4 = v[6], y4 = v[7],
|
||||
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],
|
||||
// Calculate coefficients of I(s, t), of which the roots are
|
||||
// inflection points.
|
||||
a1 = x1 * (y4 - y3) + y1 * (x3 - x4) + x4 * y3 - y4 * x3,
|
||||
a2 = x2 * (y1 - y4) + y2 * (x4 - x1) + x1 * y4 - y1 * x4,
|
||||
a3 = x3 * (y2 - y1) + y3 * (x1 - x2) + x2 * y1 - y2 * x1,
|
||||
a1 = x0 * (y3 - y2) + y0 * (x2 - x3) + x3 * y2 - y3 * x2,
|
||||
a2 = x1 * (y0 - y3) + y1 * (x3 - x0) + x0 * y3 - y0 * x3,
|
||||
a3 = x2 * (y1 - y0) + y2 * (x0 - x1) + x1 * y0 - y1 * x0,
|
||||
d3 = 3 * a3,
|
||||
d2 = d3 - a2,
|
||||
d1 = d2 - a2 + a1,
|
||||
|
@ -1607,8 +1607,8 @@ new function() { // Scope for methods that require private functions
|
|||
c = Curve.subdivide(c, a)[1]; // right
|
||||
}
|
||||
// The length of straight curves can be calculated more easily.
|
||||
var dx = c[6] - c[0], // p2x - p1x
|
||||
dy = c[7] - c[1]; // p2y - p1y
|
||||
var dx = c[6] - c[0], // x3 - x0
|
||||
dy = c[7] - c[1]; // y3 - y0
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
return Numerical.integrate(ds || getLengthIntegrand(v), a, b,
|
||||
|
@ -1993,24 +1993,24 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
|||
}
|
||||
// Avoid checking curves if completely out of control bounds.
|
||||
var epsilon = /*#=*/Numerical.EPSILON,
|
||||
c1p1x = v1[0], c1p1y = v1[1],
|
||||
c1h1x = v1[2], c1h1y = v1[3],
|
||||
c1h2x = v1[4], c1h2y = v1[5],
|
||||
c1p2x = v1[6], c1p2y = v1[7],
|
||||
c2p1x = v2[0], c2p1y = v2[1],
|
||||
c2h1x = v2[2], c2h1y = v2[3],
|
||||
c2h2x = v2[4], c2h2y = v2[5],
|
||||
c2p2x = v2[6], c2p2y = v2[7],
|
||||
c1x0 = v1[0], c1y0 = v1[1],
|
||||
c1x1 = v1[2], c1y1 = v1[3],
|
||||
c1x2 = v1[4], c1y2 = v1[5],
|
||||
c1x3 = v1[6], c1y3 = v1[7],
|
||||
c2x0 = v2[0], c2y0 = v2[1],
|
||||
c2x1 = v2[2], c2y1 = v2[3],
|
||||
c2x2 = v2[4], c2y2 = v2[5],
|
||||
c2x3 = v2[6], c2y3 = v2[7],
|
||||
min = Math.min,
|
||||
max = Math.max;
|
||||
if (!( max(c1p1x, c1h1x, c1h2x, c1p2x) + epsilon >
|
||||
min(c2p1x, c2h1x, c2h2x, c2p2x) &&
|
||||
min(c1p1x, c1h1x, c1h2x, c1p2x) - epsilon <
|
||||
max(c2p1x, c2h1x, c2h2x, c2p2x) &&
|
||||
max(c1p1y, c1h1y, c1h2y, c1p2y) + epsilon >
|
||||
min(c2p1y, c2h1y, c2h2y, c2p2y) &&
|
||||
min(c1p1y, c1h1y, c1h2y, c1p2y) - epsilon <
|
||||
max(c2p1y, c2h1y, c2h2y, c2p2y)))
|
||||
if (!( max(c1x0, c1x1, c1x2, c1x3) + epsilon >
|
||||
min(c2x0, c2x1, c2x2, c2x3) &&
|
||||
min(c1x0, c1x1, c1x2, c1x3) - epsilon <
|
||||
max(c2x0, c2x1, c2x2, c2x3) &&
|
||||
max(c1y0, c1y1, c1y2, c1y3) + epsilon >
|
||||
min(c2y0, c2y1, c2y2, c2y3) &&
|
||||
min(c1y0, c1y1, c1y2, c1y3) - epsilon <
|
||||
max(c2y0, c2y1, c2y2, c2y3)))
|
||||
return locations;
|
||||
// Now detect and handle overlaps:
|
||||
var overlaps = Curve.getOverlaps(v1, v2);
|
||||
|
@ -2046,18 +2046,18 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
|||
return locations;
|
||||
// Handle the special case where the first curve's start- or end-
|
||||
// point overlaps with the second curve's start or end-point.
|
||||
var c1p1 = new Point(c1p1x, c1p1y),
|
||||
c1p2 = new Point(c1p2x, c1p2y),
|
||||
c2p1 = new Point(c2p1x, c2p1y),
|
||||
c2p2 = new Point(c2p2x, c2p2y);
|
||||
if (c1p1.isClose(c2p1, epsilon))
|
||||
addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 0, c2p1);
|
||||
if (!param.excludeStart && c1p1.isClose(c2p2, epsilon))
|
||||
addLocation(locations, param, v1, c1, 0, c1p1, v2, c2, 1, c2p2);
|
||||
if (!param.excludeEnd && c1p2.isClose(c2p1, epsilon))
|
||||
addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 0, c2p1);
|
||||
if (c1p2.isClose(c2p2, epsilon))
|
||||
addLocation(locations, param, v1, c1, 1, c1p2, v2, c2, 1, c2p2);
|
||||
var c1p0 = new Point(c1x0, c1y0),
|
||||
c1p3 = new Point(c1x3, c1y3),
|
||||
c2p0 = new Point(c2x0, c2y0),
|
||||
c2p3 = new Point(c2x3, c2y3);
|
||||
if (c1p0.isClose(c2p0, epsilon))
|
||||
addLocation(locations, param, v1, c1, 0, c1p0, v2, c2, 0, c2p0);
|
||||
if (!param.excludeStart && c1p0.isClose(c2p3, epsilon))
|
||||
addLocation(locations, param, v1, c1, 0, c1p0, v2, c2, 1, c2p3);
|
||||
if (!param.excludeEnd && c1p3.isClose(c2p0, epsilon))
|
||||
addLocation(locations, param, v1, c1, 1, c1p3, v2, c2, 0, c2p0);
|
||||
if (c1p3.isClose(c2p3, epsilon))
|
||||
addLocation(locations, param, v1, c1, 1, c1p3, v2, c2, 1, c2p3);
|
||||
return locations;
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue