mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
More refactoring for a328f5b04b
This commit is contained in:
parent
e80b2ff043
commit
827abd21b8
2 changed files with 73 additions and 74 deletions
|
@ -622,6 +622,54 @@ statics: /** @lends Curve */{
|
|||
];
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Splits the specified curve values into segments of curves that are
|
||||
* monotone in the specified coordinate direction (0: monotone in
|
||||
* x-direction, 1: monotone in y-direction. If the curve is already
|
||||
* monotone, an array only containing the original values will be returned.
|
||||
*/
|
||||
getMonoCurves: function(v, coord) {
|
||||
var curves = [];
|
||||
// #getLength() is a rather expensive operation, therefore we test two
|
||||
// cheap preconditions first.
|
||||
if (v[0] === v[6] && v[1] === v[7] && Curve.getLength(v) === 0)
|
||||
return curves;
|
||||
var o0 = v[1 - coord],
|
||||
o1 = v[3 - coord],
|
||||
o2 = v[5 - coord],
|
||||
o3 = v[7 - coord];
|
||||
if ((o0 >= o1) === (o1 >= o2) && (o1 >= o2) === (o2 >= o3)
|
||||
|| Curve.isStraight(v)) {
|
||||
// Straight curves and curves with points and control points ordered
|
||||
// in coordinate direction are guaranteed to be monotone.
|
||||
curves.push(v);
|
||||
} else {
|
||||
var a = 3 * (o1 - o2) - o0 + o3,
|
||||
b = 2 * (o0 + o2) - 4 * o1,
|
||||
c = o1 - o0,
|
||||
tMin = 4e-7,
|
||||
tMax = 1 - tMin,
|
||||
roots = [],
|
||||
n = Numerical.solveQuadratic(a, b, c, roots, tMin, tMax);
|
||||
if (n === 0) {
|
||||
curves.push(v);
|
||||
} else {
|
||||
roots.sort();
|
||||
var t = roots[0],
|
||||
parts = Curve.subdivide(v, t);
|
||||
curves.push(parts[0]);
|
||||
if (n > 1) {
|
||||
t = (roots[1] - t) / (1 - t);
|
||||
parts = Curve.subdivide(parts[1], t);
|
||||
curves.push(parts[0]);
|
||||
}
|
||||
curves.push(parts[1]);
|
||||
}
|
||||
}
|
||||
return curves;
|
||||
},
|
||||
|
||||
// Converts from the point coordinates (p1, c1, c2, p2) for one axis to
|
||||
// the polynomial coefficients and solves the polynomial for val
|
||||
solveCubic: function (v, coord, val, roots, min, max) {
|
||||
|
@ -822,53 +870,6 @@ statics: /** @lends Curve */{
|
|||
+ t * t * t * v3,
|
||||
padding);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Splits the specified curve values into segments of curves that are
|
||||
* monotone in the specified coordinate direction (0: monotone in
|
||||
* x-direction, 1: monotone in y-direction. If the curve is already
|
||||
* monotone, an array only containing the original values will be returned.
|
||||
*/
|
||||
splitToMonoCurves: function(v, coord) {
|
||||
var vMono = [];
|
||||
// #getLength() is a rather expensive operation, therefore we test two
|
||||
// cheap preconditions first.
|
||||
if (v[0] === v[6] && v[1] === v[7] && Curve.getLength(v) === 0)
|
||||
return vMono;
|
||||
var o0 = v[1 - coord],
|
||||
o1 = v[3 - coord],
|
||||
o2 = v[5 - coord],
|
||||
o3 = v[7 - coord];
|
||||
if ((o0 >= o1) === (o1 >= o2) && (o1 >= o2) === (o2 >= o3)
|
||||
|| Curve.isStraight(v)) {
|
||||
// Straight curves and curves with points and control points ordered
|
||||
// in coordinate direction are guaranteed to be monotone.
|
||||
vMono.push(v);
|
||||
} else {
|
||||
var a = 3 * (o1 - o2) - o0 + o3,
|
||||
b = 2 * (o0 + o2) - 4 * o1,
|
||||
c = o1 - o0,
|
||||
tMin = 4e-7,
|
||||
tMax = 1 - tMin,
|
||||
roots = [],
|
||||
n = Numerical.solveQuadratic(a, b, c, roots, tMin, tMax);
|
||||
if (n === 0) {
|
||||
vMono.push(v);
|
||||
} else {
|
||||
roots.sort();
|
||||
var t = roots[0],
|
||||
parts = Curve.subdivide(v, t);
|
||||
vMono.push(parts[0]);
|
||||
if (n > 1) {
|
||||
t = (roots[1] - t) / (1 - t);
|
||||
parts = Curve.subdivide(parts[1], t);
|
||||
vMono.push(parts[0]);
|
||||
}
|
||||
vMono.push(parts[1]);
|
||||
}
|
||||
}
|
||||
return vMono;
|
||||
}
|
||||
}}, Base.each(
|
||||
['getBounds', 'getStrokeBounds', 'getHandleBounds'],
|
||||
|
|
|
@ -452,7 +452,7 @@ PathItem.inject(new function() {
|
|||
( v[coord] > aAfter && v[2 + coord] > aAfter &&
|
||||
v[4 + coord] > aAfter && v[6 + coord] > aAfter)
|
||||
? [v]
|
||||
: Curve.splitToMonoCurves(v, coord);
|
||||
: Curve.getMonoCurves(v, coord);
|
||||
for (var j = 0, m = monoCurves.length; j < m; j++) {
|
||||
vPrev = addWinding(monoCurves[j], vPrev, point.x, point.y,
|
||||
windings, isOnPath, coord);
|
||||
|
@ -980,44 +980,42 @@ Path.inject(/** @lends Path# */{
|
|||
var bounds = this.getBounds(),
|
||||
point = bounds.getCenter(true);
|
||||
if (!this.contains(point)) {
|
||||
// Since there is no guarantee that a poly-bezier path contains
|
||||
// the center of its bounding rectangle, we shoot a ray in
|
||||
// x direction and select a point between the first consecutive
|
||||
// intersections of the ray on the left.
|
||||
// Since there is no guarantee that a poly-bezier path contains the
|
||||
// center of its bounding rectangle, we shoot a ray in x direction
|
||||
// and select a point between the first consecutive intersections of
|
||||
// the ray on the left.
|
||||
var curves = this.getCurves(),
|
||||
y = point.y,
|
||||
intercepts = [],
|
||||
monoCurves = [];
|
||||
// Collect values for all y-monotone curves that intersect the ray at y
|
||||
monoCurves = [],
|
||||
roots = [],
|
||||
windingPrev = 0;
|
||||
// Get values for all y-monotone curves that intersect the ray at y.
|
||||
for (var i = 0, l = curves.length; i < l; i++) {
|
||||
var monoVals = Curve.splitToMonoCurves(curves[i].getValues(), 0);
|
||||
for (var j = 0; j < monoVals.length; j++) {
|
||||
var values = monoVals[j];
|
||||
if (y >= values[1] && y <= values[7]
|
||||
|| y >= values[7] && y <= values[1]) {
|
||||
var winding = values[1] > values[7] ? 1 : values[1] < values[7] ? -1 : 0;
|
||||
var monos = Curve.getMonoCurves(curves[i].getValues(), 0);
|
||||
for (var j = 0, m = monos.length; j < m; j++) {
|
||||
var v = monos[j];
|
||||
if (y >= v[1] && y <= v[7] || y >= v[7] && y <= v[1]) {
|
||||
var winding = v[1] > v[7] ? 1 : v[1] < v[7] ? -1 : 0;
|
||||
if (winding) {
|
||||
monoCurves.push({values: values, winding: winding});
|
||||
monoCurves.push({ values: v, winding: winding });
|
||||
windingPrev = winding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!monoCurves.length) {
|
||||
// fallback in case no non-horizontal curves were found
|
||||
// Fallback in case no non-horizontal curves were found.
|
||||
if (!monoCurves.length)
|
||||
return point;
|
||||
}
|
||||
var windingPrev = monoCurves[monoCurves.length - 1].winding;
|
||||
for (var i = 0, l = monoCurves.length; i < l; i++) {
|
||||
var v = monoCurves[i].values;
|
||||
var winding = monoCurves[i].winding;
|
||||
var roots = [];
|
||||
var x = y === v[1] ? v[0]
|
||||
: y === v[7] ? v[6]
|
||||
: Curve.solveCubic(v, 1, y, roots, 0, 1) === 1
|
||||
? Curve.getPoint(v, roots[0]).x
|
||||
: (v[0] + v[6]) / 2;
|
||||
//if (y != v[1] || winding != windingPrev)
|
||||
var v = monoCurves[i].values,
|
||||
winding = monoCurves[i].winding,
|
||||
x = y === v[1] ? v[0]
|
||||
: y === v[7] ? v[6]
|
||||
: Curve.solveCubic(v, 1, y, roots, 0, 1) === 1
|
||||
? Curve.getPoint(v, roots[0]).x
|
||||
: (v[0] + v[6]) / 2;
|
||||
// if (y != v[1] || winding != windingPrev)
|
||||
intercepts.push(x);
|
||||
windingPrev = winding;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue