Go back to simple overlap handling.

It appears to produce less glitches.
This commit is contained in:
Jürg Lehni 2015-10-11 17:05:23 +02:00
parent 4500e520ea
commit bbc0029252
2 changed files with 15 additions and 40 deletions

View file

@ -60,7 +60,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
this._setCurve(curve);
this._parameter = parameter;
this._point = point || curve.getPointAt(parameter, true);
this._overlaps = _overlap ? [_overlap] : null;
this._overlap = _overlap;
this._distance = _distance;
this._intersection = this._next = this._prev = null;
},
@ -454,7 +454,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
* @see #isTouching()
*/
isOverlap: function() {
return !!this._overlaps;
return !!this._overlap;
}
}, Base.each(Curve.evaluateMethods, function(name) {
// Produce getters for #getTangent() / #getNormal() / #getCurvature()
@ -478,16 +478,6 @@ new function() { // Scope for statics
: path1._id - path2._id;
}
function addOverlaps(loc1, loc2) {
var overlaps1 = loc1._overlaps,
overlaps2 = loc2._overlaps;
if (overlaps1) {
overlaps1.push.apply(overlaps1, overlaps2);
} else {
loc1._overlaps = overlaps2.slice();
}
}
function insert(locations, loc, merge) {
// Insert-sort by path-id, curve, parameter so we can easily merge
// duplicates with calls to equals() after.
@ -527,10 +517,9 @@ new function() { // Scope for statics
if (loc2 = loc.equals(loc2) ? loc2
: search(m, -1) || search(m, 1)) {
// We're done, don't insert, merge with the found location
// instead, and carry over overlaps:
if (loc._overlaps) {
addOverlaps(loc2, loc);
addOverlaps(loc2._intersection, loc._intersection);
// instead, and carry over overlap:
if (loc._overlap) {
loc2._overlap = loc2._intersection._overlap = true;
}
return loc2;
}

View file

@ -165,10 +165,10 @@ PathItem.inject(new function() {
var other = inter._intersection;
var log = [title, inter._id, 'id', inter.getPath()._id,
'i', inter.getIndex(), 't', inter._parameter,
'o', !!inter._overlaps, 'p', inter.getPoint(),
'o', !!inter._overlap, 'p', inter.getPoint(),
'Other', other._id, 'id', other.getPath()._id,
'i', other.getIndex(), 't', other._parameter,
'o', !!other._overlaps, 'p', other.getPoint()];
'o', !!other._overlap, 'p', other.getPoint()];
console.log(log.map(function(v) {
return v == null ? '-' : v
}).join(' '));
@ -536,7 +536,7 @@ PathItem.inject(new function() {
+ ' v: ' + (seg._visited ? 1 : 0)
+ ' p: ' + seg._point
+ ' op: ' + isValid(seg)
+ ' ov: ' + !!(inter && inter._overlaps)
+ ' ov: ' + !!(inter && inter._overlap)
+ ' wi: ' + seg._winding
+ ' mu: ' + !!(inter && inter._next)
, color);
@ -574,7 +574,7 @@ PathItem.inject(new function() {
+ ' n3x: ' + (n3xs && n3xs._path._id + '.' + n3xs._index
+ '(' + n3x._id + ')' || '--')
+ ' pt: ' + seg._point
+ ' ov: ' + !!(inter && inter._overlaps)
+ ' ov: ' + !!(inter && inter._overlap)
+ ' wi: ' + seg._winding
, item.strokeColor || item.fillColor || 'black');
}
@ -596,7 +596,7 @@ PathItem.inject(new function() {
return true;
var winding = seg._winding,
inter = seg._intersection;
if (inter && !unadjusted && overlapWinding && inter._overlaps)
if (inter && !unadjusted && overlapWinding && inter._overlap)
winding = overlapWinding[winding] || winding;
return operator(winding);
}
@ -605,20 +605,6 @@ PathItem.inject(new function() {
return seg === start || seg === otherStart;
}
/**
* Checks if the curve from seg1 to seg2 is part of an overlap.
*/
function isOverlap(seg1, seg2) {
var inter = seg2._intersection,
overlaps = inter && inter._overlaps,
values = Curve.getValues(seg1, seg2);
for (var i = 0, l = overlaps && overlaps.length; i < l; i++) {
if (Curve.getOverlaps(values, overlaps[i]))
return true;
}
return false;
}
// If there are multiple possible intersections, find the one
// that's either connecting back to start or is not visited yet,
// and will be part of the boolean result:
@ -641,14 +627,14 @@ PathItem.inject(new function() {
+ ', next wi:' + nextSeg._winding
+ ', seg op:' + isValid(seg, true)
+ ', next op:'
+ (!(strict && isOverlap(seg, nextSeg))
+ (!(strict && nextInter && nextInter._overlap)
&& isValid(nextSeg, true)
|| !strict && nextInter
&& isValid(nextInter._segment, true))
+ ', seg ov: ' + !!(seg._intersection
&& seg._intersection._overlaps)
&& seg._intersection._overlap)
+ ', next ov: ' + !!(nextSeg._intersection
&& nextSeg._intersection._overlaps)
&& nextSeg._intersection._overlap)
+ ', more: ' + (!!inter._next));
}
// See if this segment and the next are both not visited yet, or
@ -674,7 +660,7 @@ PathItem.inject(new function() {
// Do not consider nextSeg in strict mode if it is part
// of an overlap, in order to give non-overlapping
// options that might follow the priority over overlaps.
&& (!(strict && isOverlap(seg, nextSeg))
&& (!(strict && nextInter && nextInter._overlap)
&& isValid(nextSeg, true)
// If the next segment isn't valid, its intersection
// to which we may switch might be, so check that.
@ -741,7 +727,7 @@ PathItem.inject(new function() {
// Switch to the intersecting segment, as we need to
// resolving self-Intersections.
seg = other;
} else if (inter._overlaps && operation !== 'intersect') {
} else if (inter._overlap && operation !== 'intersect') {
// Switch to the overlapping intersecting segment if it is
// part of the boolean result. Do not adjust for overlap!
if (isValid(other, true)) {