mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Improve handling of straight closing curves in open path checks.
This commit is contained in:
parent
e643338422
commit
aee9a3190d
4 changed files with 32 additions and 39 deletions
|
@ -251,11 +251,11 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
|
|||
* @bean
|
||||
* @type Number
|
||||
*/
|
||||
getArea: function(_closed) {
|
||||
getArea: function() {
|
||||
var children = this._children,
|
||||
area = 0;
|
||||
for (var i = 0, l = children.length; i < l; i++)
|
||||
area += children[i].getArea(_closed);
|
||||
area += children[i].getArea();
|
||||
return area;
|
||||
},
|
||||
|
||||
|
|
|
@ -577,17 +577,21 @@ var Curve = Base.extend(/** @lends Curve# */{
|
|||
},
|
||||
|
||||
statics: /** @lends Curve */{
|
||||
getValues: function(segment1, segment2, matrix) {
|
||||
getValues: function(segment1, segment2, matrix, straight) {
|
||||
var p1 = segment1._point,
|
||||
h1 = segment1._handleOut,
|
||||
h2 = segment2._handleIn,
|
||||
p2 = segment2._point,
|
||||
values = [
|
||||
p1._x, p1._y,
|
||||
p1._x + h1._x, p1._y + h1._y,
|
||||
p2._x + h2._x, p2._y + h2._y,
|
||||
p2._x, p2._y
|
||||
];
|
||||
x1 = p1.x, y1 = p1.y,
|
||||
x2 = p2.x, y2 = p2.y,
|
||||
values = straight
|
||||
? [ x1, y1, x1, y1, x2, y2, x2, y2 ]
|
||||
: [
|
||||
x1, y1,
|
||||
x1 + h1._x, y1 + h1._y,
|
||||
x2 + h2._x, y2 + h2._y,
|
||||
x2, y2
|
||||
];
|
||||
if (matrix)
|
||||
matrix._transformCoordinates(values, values, 4);
|
||||
return values;
|
||||
|
|
|
@ -828,29 +828,23 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* @bean
|
||||
* @type Number
|
||||
*/
|
||||
getArea: function(_closed) {
|
||||
// Cache the area for the open path, and the the final curve separately,
|
||||
// so open and closed area can be returned at almost no additional cost.
|
||||
var closed = Base.pick(_closed, this._closed),
|
||||
cached = this._area;
|
||||
if (cached == null) {
|
||||
getArea: function() {
|
||||
var area = this._area;
|
||||
if (area == null) {
|
||||
var segments = this._segments,
|
||||
sum = 0,
|
||||
close = 0;
|
||||
closed = this._closed;
|
||||
area = 0;
|
||||
for (var i = 0, l = segments.length; i < l; i++) {
|
||||
var next = i + 1,
|
||||
last = next >= l,
|
||||
area = Curve.getArea(Curve.getValues(
|
||||
segments[i], segments[last ? 0 : i + 1]));
|
||||
if (last) {
|
||||
close = area;
|
||||
} else {
|
||||
sum += area;
|
||||
}
|
||||
var last = i + 1 === l;
|
||||
area += Curve.getArea(Curve.getValues(
|
||||
segments[i], segments[last ? 0 : i + 1],
|
||||
// If this is the last curve and the last is not closed,
|
||||
// connect with a straight curve and ignore the handles.
|
||||
null, last && !closed));
|
||||
}
|
||||
cached = this._area = [sum, close];
|
||||
this._area = area;
|
||||
}
|
||||
return cached[0] + (closed ? cached[1] : 0);
|
||||
return area;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -95,7 +95,7 @@ PathItem.inject(new function() {
|
|||
// Give both paths the same orientation except for subtraction
|
||||
// and exclusion, where we need them at opposite orientation.
|
||||
if (_path2 && (operator.subtract || operator.exclude)
|
||||
^ (_path2.isClockwise(true) ^ _path1.isClockwise(true)))
|
||||
^ (_path2.isClockwise() ^ _path1.isClockwise()))
|
||||
_path2.reverse();
|
||||
// Split curves at crossings on both paths. Note that for self-
|
||||
// intersection, path2 is null and getIntersections() handles it.
|
||||
|
@ -510,15 +510,10 @@ PathItem.inject(new function() {
|
|||
// - `true`: Connect with a curve that takes the segment handles
|
||||
// into account, just like how closed paths behave.
|
||||
if (!path._closed) {
|
||||
var s1 = path.getLastCurve().getSegment2(),
|
||||
s2 = curve.getSegment1(),
|
||||
p1 = s1._point,
|
||||
p2 = s2._point,
|
||||
x1 = p1._x, y1 = p1._y,
|
||||
x2 = p2._x, y2 = p2._y;
|
||||
vClose = closed
|
||||
? Curve.getValues(s1, s2)
|
||||
: [x1, y1, x1, y1, x2, y2, x2, y2];
|
||||
vClose = Curve.getValues(
|
||||
path.getLastCurve().getSegment2(),
|
||||
curve.getSegment1(),
|
||||
null, !closed);
|
||||
// This closing curve is a potential candidate for the last
|
||||
// non-horizontal curve.
|
||||
if (vClose[io] !== vClose[io + 6]) {
|
||||
|
@ -850,7 +845,7 @@ PathItem.inject(new function() {
|
|||
// close to each other that they are considered the same
|
||||
// location, but the winding calculation still produces a valid
|
||||
// number due to their slight differences producing a tiny area.
|
||||
var area = path.getArea(true);
|
||||
var area = path.getArea();
|
||||
if (abs(area) >= /*#=*/Numerical.GEOMETRIC_EPSILON) {
|
||||
// This path wasn't finished and is hence invalid.
|
||||
// Report the error to the console for the time being.
|
||||
|
|
Loading…
Reference in a new issue