Restructure code that determines median winding contribution.

This commit is contained in:
Jürg Lehni 2015-01-03 00:26:13 +01:00
parent 5f0e545ba7
commit bb2fece225

View file

@ -63,7 +63,6 @@ PathItem.inject(new function() {
var chain = [], var chain = [],
windings = [], windings = [],
lengths = [],
segments = [], segments = [],
// Aggregate of all curves in both operands, monotonic in y // Aggregate of all curves in both operands, monotonic in y
monoCurves = []; monoCurves = [];
@ -96,12 +95,13 @@ PathItem.inject(new function() {
// contribution for this curve-chain. Once we have enough confidence // contribution for this curve-chain. Once we have enough confidence
// in the winding contribution, we can propagate it until the // in the winding contribution, we can propagate it until the
// intersection or end of a curve chain. // intersection or end of a curve chain.
chain.length = windings.length = lengths.length = 0; chain.length = 0;
var totalLength = 0, var startSeg = segment,
startSeg = segment; totalLength = 0;
do { do {
chain.push(segment); var length = segment.getCurve().getLength();
lengths.push(totalLength += segment.getCurve().getLength()); chain.push({ segment: segment, length: length });
totalLength += length;
segment = segment.getNext(); segment = segment.getNext();
} while (segment && !segment._intersection && segment !== startSeg); } while (segment && !segment._intersection && segment !== startSeg);
// Select the median winding of three random points along this curve // Select the median winding of three random points along this curve
@ -109,36 +109,34 @@ PathItem.inject(new function() {
// gives a better chance of returning a correct winding than equally // gives a better chance of returning a correct winding than equally
// dividing the curve chain, with the same (amortised) time. // dividing the curve chain, with the same (amortised) time.
for (var j = 0; j < 3; j++) { for (var j = 0; j < 3; j++) {
var length = totalLength * Math.random(), var length = totalLength * Math.random();
amount = lengths.length, for (k = 0, m = chain.length; k < m; k++) {
k = 0; var entry = chain[k];
do { if (length <= entry.length) {
if (lengths[k] >= length) { var curve = entry.segment.getCurve(),
if (k > 0) pt = curve.getPointAt(length),
length -= lengths[k - 1]; hor = curve.isHorizontal(),
path = curve._path;
if (path._parent instanceof CompoundPath)
path = path._parent;
// While subtracting, we need to omit this curve if this
// curve is contributing to the second operand and is
// outside the first operand.
windings[j] = subtract && _path2
&& (path === _path1 && _path2._getWinding(pt, hor)
|| path === _path2 && !_path1._getWinding(pt, hor))
? 0
: getWinding(pt, monoCurves, hor);
break; break;
} }
} while (++k < amount); length -= entry.length;
var curve = chain[k].getCurve(), }
point = curve.getPointAt(length),
hor = curve.isHorizontal(),
path = curve._path;
if (path._parent instanceof CompoundPath)
path = path._parent;
// While subtracting, we need to omit this curve if this
// curve is contributing to the second operand and is outside
// the first operand.
windings[j] = subtract && _path2
&& (path === _path1 && _path2._getWinding(point, hor)
|| path === _path2 && !_path1._getWinding(point, hor))
? 0
: getWinding(point, monoCurves, hor);
} }
windings.sort(); windings.sort();
// Assign the median winding to the entire curve chain. // Assign the median winding to the entire curve chain.
var winding = windings[1]; var winding = windings[1];
for (var j = chain.length - 1; j >= 0; j--) for (var j = chain.length - 1; j >= 0; j--)
chain[j]._winding = winding; chain[j].segment._winding = winding;
} }
// Trace closed contours and insert them into the result. // Trace closed contours and insert them into the result.
var result = new CompoundPath(); var result = new CompoundPath();