Winding: More work on handling overlaps in getWinding()

Includes debug logging for now. Relates to #1116
This commit is contained in:
Jürg Lehni 2016-07-23 17:19:28 +02:00
parent 83148a2c72
commit 4680fd3f60
2 changed files with 38 additions and 18 deletions

View file

@ -429,7 +429,7 @@ PathItem.inject(new function() {
a3Prev = vPrev[ia + 6], a3Prev = vPrev[ia + 6],
curveWindingL = 0, curveWindingL = 0,
curveWindingR = 0, curveWindingR = 0,
onCurve = false; onCurve = a > paL && a < paR;
if (po !== o0) { if (po !== o0) {
// Standard case, curve is not crossed at its starting point. // Standard case, curve is not crossed at its starting point.
if (a < paL) { if (a < paL) {
@ -437,9 +437,9 @@ PathItem.inject(new function() {
} else if (a > paR) { } else if (a > paR) {
curveWindingR = winding; curveWindingR = winding;
} else { } else {
onCurve = true; onPath = true;
pathWindingL += winding; curveWindingL = winding;
pathWindingR += winding; curveWindingR = winding;
} }
} else if (winding !== windingPrev) { } else if (winding !== windingPrev) {
// Curve is crossed at starting point and winding changes from // Curve is crossed at starting point and winding changes from
@ -453,7 +453,7 @@ PathItem.inject(new function() {
} else if (a3Prev < paL && a > paL || a3Prev > paR && a < paR) { } else if (a3Prev < paL && a > paL || a3Prev > paR && a < paR) {
// Point is on a horizontal curve between the previous non- // Point is on a horizontal curve between the previous non-
// horizontal and the current curve. // horizontal and the current curve.
onCurve = true; onPath = true;
if (a3Prev < paL) { if (a3Prev < paL) {
// left winding was added before, now add right winding. // left winding was added before, now add right winding.
curveWindingR = winding; curveWindingR = winding;
@ -462,18 +462,18 @@ PathItem.inject(new function() {
curveWindingL = winding; curveWindingL = winding;
} }
} }
vPrev = v; pathWindingL += curveWindingL;
pathWindingR += curveWindingR;
if (onCurve) { if (onCurve) {
onCurves.push({ onCurves.push({
curve: v, curve: v,
time: t,
winding: winding, winding: winding,
windingL: curveWindingL, windingL: curveWindingL,
windingR: curveWindingR, windingR: curveWindingR
}); });
onPath = true;
} }
pathWindingL += curveWindingL; vPrev = v;
pathWindingR += curveWindingR;
// If we're on the curve, look at the tangent to decide whether to // If we're on the curve, look at the tangent to decide whether to
// flip direction to determine a reliable winding number: // flip direction to determine a reliable winding number:
// If the tangent is parallel to the direction, call getWinding() // If the tangent is parallel to the direction, call getWinding()
@ -586,18 +586,37 @@ PathItem.inject(new function() {
} }
} }
for (var i = 0; i < onCurves.length - 1; i++) { console.log('before', windingL, windingR, onCurves);
var entry1 = onCurves[i], for (var i = 0; i < onCurves.length; i++) {
hasOverlaps = false; var entry1 = onCurves[i];
for (var j = i + 1; !hasOverlaps && j < onCurves.length; j++) { if (i > 0) {
var entry2 = onCurves[j];
hasOverlaps = !!Curve.getOverlaps(entry1.curve, entry2.curve);
}
if (!hasOverlaps) {
windingL -= entry1.windingL; windingL -= entry1.windingL;
windingR -= entry1.windingR; windingR -= entry1.windingR;
} }
for (var j = i + 1; j < onCurves.length; j++) {
var entry2 = onCurves[j],
v1 = entry1.curve,
v2 = entry2.curve,
overlaps = Curve.getOverlaps(v1, v2);
if (overlaps) {
var t1 = entry1.time,
t2 = entry2.time,
start1 = overlaps[0][0],
start2 = overlaps[0][1],
end1 = overlaps[1][0],
end2 = overlaps[1][1];
console.log('overlap', t1, start1, end1, t2, start2, end2);
if (t1 >= min(start1, end1) && t1 <= max(start1, end1) &&
t2 >= min(start2, end2) && t2 <= max(start2, end2)) {
var dir = start1 < end1 === start2 < end2;
console.log('overlap', dir, entry1.winding, entry2.winding);
windingL += entry2.windingL;
windingR += entry2.windingR;
}
}
}
} }
console.log('after', windingL, windingR);
if (!windingL && !windingR) { if (!windingL && !windingR) {
windingL = windingR = onPathWinding; windingL = windingR = onPathWinding;

View file

@ -267,6 +267,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{
this.getBounds({ internal: true, handle: true })) this.getBounds({ internal: true, handle: true }))
? this._getWinding(point) ? this._getWinding(point)
: {}; : {};
console.log(JSON.stringify(winding));
return !!(this.getFillRule() === 'evenodd' return !!(this.getFillRule() === 'evenodd'
? winding.windingL & 1 || winding.windingR & 1 ? winding.windingL & 1 || winding.windingR & 1
: winding.winding); : winding.winding);