mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-20 22:39:50 -05:00
Fix issues with wrong sorting of CurveLocation in Curve.filterIntersections()
This commit is contained in:
parent
815991d556
commit
d85b4f0c80
4 changed files with 55 additions and 24 deletions
|
@ -1623,34 +1623,19 @@ new function() { // Scope for methods that require private functions
|
|||
// Merge intersections very close to the end of a curve to the
|
||||
// beginning of the next curve.
|
||||
for (var i = last; i >= 0; i--) {
|
||||
var loc = locations[i],
|
||||
next = loc._curve.getNext(),
|
||||
next2 = loc._curve2.getNext();
|
||||
if (next && loc._parameter >= tMax) {
|
||||
var loc = locations[i];
|
||||
if (loc._parameter >= tMax && (next = loc._curve.getNext())) {
|
||||
loc._parameter = 0;
|
||||
loc._curve = next;
|
||||
}
|
||||
if (next2 && loc._parameter2 >= tMax) {
|
||||
if (loc._parameter2 >= tMax && (next = loc._curve2.getNext())) {
|
||||
loc._parameter2 = 0;
|
||||
loc._curve2 = next2;
|
||||
loc._curve2 = next;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare helper to filter locations
|
||||
function compare(loc1, loc2) {
|
||||
var path1 = loc1.getPath(),
|
||||
path2 = loc2.getPath();
|
||||
return path1 === path2
|
||||
// We can add parameter (0 <= t <= 1) to index
|
||||
// (a integer) to compare both at the same time.
|
||||
? (loc1.getIndex() + loc1.getParameter())
|
||||
- (loc2.getIndex() + loc2.getParameter())
|
||||
// Sort by path id to group all locs on the same path.
|
||||
: path1._id - path2._id;
|
||||
}
|
||||
|
||||
if (last > 0) {
|
||||
locations.sort(compare);
|
||||
CurveLocation.sort(locations);
|
||||
// Filter out duplicate locations, but preserve _overlap setting
|
||||
// among all duplicated (only one of them will have it defined).
|
||||
var i = last,
|
||||
|
@ -1671,7 +1656,7 @@ new function() { // Scope for methods that require private functions
|
|||
if (expand) {
|
||||
for (var i = last; i >= 0; i--)
|
||||
locations.push(locations[i].getIntersection());
|
||||
locations.sort(compare);
|
||||
CurveLocation.sort(locations);
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
this._parameter2, this._point2 || this._point);
|
||||
intersection._overlap = this._overlap;
|
||||
intersection._intersection = this;
|
||||
intersection._other = true;
|
||||
}
|
||||
return intersection;
|
||||
},
|
||||
|
@ -286,6 +287,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
&& abs(this.getParameter() - loc.getParameter()) < tolerance
|
||||
// _curve2/_parameter2 are only used for Boolean operations
|
||||
// and don't need syncing there.
|
||||
// TODO: That's not quite true though... Rework this!
|
||||
&& this._curve2 === loc._curve2
|
||||
&& abs((this._parameter2 || 0) - (loc._parameter2 || 0))
|
||||
< tolerance
|
||||
|
@ -310,6 +312,30 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
if (this._distance != null)
|
||||
parts.push('distance: ' + f.number(this._distance));
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
},
|
||||
|
||||
statics: {
|
||||
sort: function(locations) {
|
||||
var tolerance = 1 - /*#=*/Numerical.TOLERANCE;
|
||||
locations.sort(function compare(l1, l2) {
|
||||
var curve1 = l1._curve,
|
||||
curve2 = l2._curve,
|
||||
path1 = curve1._path,
|
||||
path2 = curve2._path;
|
||||
// Sort by path-id, curve, parameter, curve2, parameter2 so we
|
||||
// can easily remove duplicates with calls to equals() after.
|
||||
return path1 === path2
|
||||
? curve1 === curve2
|
||||
? Math.abs(l1._parameter - l2._parameter) < tolerance
|
||||
? l1._curve2 === l2._curve2
|
||||
? l1._parameter2 - l2._parameter2
|
||||
: l1._curve2.getIndex() - l2._curve2.getIndex()
|
||||
: l1._parameter - l2._parameter
|
||||
: curve1.getIndex() - curve2.getIndex()
|
||||
// Sort by path id to group all locs on the same path.
|
||||
: path1._id - path2._id;
|
||||
});
|
||||
}
|
||||
}
|
||||
}, Base.each(Curve.evaluateMethods, function(name) {
|
||||
// Produce getters for #getTangent() / #getNormal() / #getCurvature()
|
||||
|
|
|
@ -1191,8 +1191,9 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
index = arg.index;
|
||||
parameter = arg.parameter;
|
||||
}
|
||||
var tolerance = /*#=*/Numerical.TOLERANCE;
|
||||
if (parameter >= 1 - tolerance) {
|
||||
var tMin = /*#=*/Numerical.TOLERANCE,
|
||||
tMax = 1 - tMin;
|
||||
if (parameter >= tMax) {
|
||||
// t == 1 is the same as t == 0 and index ++
|
||||
index++;
|
||||
parameter--;
|
||||
|
@ -1200,7 +1201,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
var curves = this.getCurves();
|
||||
if (index >= 0 && index < curves.length) {
|
||||
// Only divide curves if we're not on an existing segment already.
|
||||
if (parameter >= tolerance) {
|
||||
if (parameter >= tMin) {
|
||||
// Divide the curve with the index at given parameter.
|
||||
// Increase because dividing adds more segments to the path.
|
||||
curves[index++].divide(parameter, true);
|
||||
|
|
|
@ -220,6 +220,24 @@ PathItem.inject(new function() {
|
|||
* @param {CurveLocation[]} intersections Array of CurveLocation objects
|
||||
*/
|
||||
function splitPath(intersections) {
|
||||
console.log('splitting', intersections.length);
|
||||
intersections.forEach(function(inter) {
|
||||
var log = ['CurveLocation', inter._id, 'p', inter.getPath()._id,
|
||||
'i', inter.getIndex(), 't', inter._parameter,
|
||||
'i2', inter._curve2 ? inter._curve2.getIndex() : null,
|
||||
't2', inter._parameter2, 'o', !!inter._overlap];
|
||||
if (inter._other) {
|
||||
inter = inter.getIntersection();
|
||||
log.push('Other', inter._id, 'p', inter.getPath()._id,
|
||||
'i', inter.getIndex(), 't', inter._parameter,
|
||||
'i2', inter._curve2 ? inter._curve2.getIndex() : null,
|
||||
't2', inter._parameter2, 'o', !!inter._overlap);
|
||||
}
|
||||
console.log(log.map(function(v) {
|
||||
return v == null ? '-' : v
|
||||
}).join(' '));
|
||||
});
|
||||
|
||||
// TODO: Make public in API, since useful!
|
||||
var tMin = /*#=*/Numerical.TOLERANCE,
|
||||
tMax = 1 - tMin,
|
||||
|
@ -466,6 +484,7 @@ PathItem.inject(new function() {
|
|||
inter = seg._intersection;
|
||||
labelSegment(seg, i
|
||||
+ ' i: ' + !!inter
|
||||
+ ' p: ' + seg._path._id
|
||||
+ ' o: ' + (inter && inter._overlap || 0)
|
||||
+ ' w: ' + seg._winding
|
||||
, 'green');
|
||||
|
|
Loading…
Reference in a new issue