Correct winding contribution calculation for horizontal curves

This commit is contained in:
hkrish 2014-01-16 19:59:18 +01:00
parent df7e8e43b2
commit 24cbf3b079
3 changed files with 11 additions and 50 deletions

View file

@ -1719,7 +1719,6 @@ var Path = PathItem.extend(/** @lends Path# */{
_getMonotoneCurves: function() {
var monoCurves = this._monotoneCurves,
lastCurve,
// TODO: replace instances with constants ( /*#=*/ ?)
INCREASING = 1,
DECREASING = -1,
HORIZONTAL = 0;
@ -1818,49 +1817,6 @@ var Path = PathItem.extend(/** @lends Path# */{
return monoCurves;
},
// _getWinding: function(point) {
// var closed = this._closed;
// // If the path is not closed, we should not bail out in case it has a
// // fill color!
// if (!closed && !this.hasFill()
// || !this.getInternalRoughBounds()._containsPoint(point))
// return 0;
// // Use the crossing number algorithm, by counting the crossings of the
// // beam in right y-direction with the shape, and see if it's an odd
// // number, meaning the starting point is inside the shape.
// // http://en.wikipedia.org/wiki/Point_in_polygon
// var curves = this.getCurves(),
// segments = this._segments,
// winding = 0,
// // Reuse arrays for root-finding, give garbage collector a break
// roots1 = [],
// roots2 = [],
// last = (closed
// ? curves[curves.length - 1]
// // Create a straight closing line for open paths, just like
// // how filling open paths works.
// : new Curve(segments[segments.length - 1]._point,
// segments[0]._point)).getValues(),
// previous = last;
// for (var i = 0, l = curves.length; i < l; i++) {
// var curve = curves[i].getValues(),
// x = curve[0],
// y = curve[1];
// // Filter out curves with 0-length (all 4 points in the same place):
// if (!(x === curve[2] && y === curve[3] && x === curve[4]
// && y === curve[5] && x === curve[6] && y === curve[7])) {
// winding += Curve._getWinding(curve, previous, point.x, point.y,
// roots1, roots2);
// previous = curve;
// }
// }
// if (!closed) {
// winding += Curve._getWinding(last, previous, point.x, point.y,
// roots1, roots2);
// }
// return winding;
// },
_hitTest: function(point, options) {
var that = this,
style = this.getStyle(),

View file

@ -86,7 +86,7 @@ PathItem.inject(new function() { // FIXME: Is new necessary?
if (!(reverse ^ path2.isClockwise()))
path2.reverse();
var intersections, i, j, l, lj, segment, wind,
point, startSeg, crv, length, parent,
point, startSeg, crv, length, parent, v, horizontal,
curveChain = [],
windings = [],
lengths = [],
@ -96,7 +96,10 @@ PathItem.inject(new function() { // FIXME: Is new necessary?
// Aggregate of all curves in both operands, monotonic in y
monoCurves = [],
result = new CompoundPath(),
random = Math.random;
random = Math.random,
abs = Math.abs,
tolerance = Numerical.TOLERANCE,
getWindingNumber = PathItem._getWindingNumber;
// Split curves at intersections on both paths.
intersections = path1.getIntersections(path2);
PathItem._splitPath(intersections);
@ -160,7 +163,10 @@ PathItem.inject(new function() { // FIXME: Is new necessary?
}
crv = curveChain[j].getCurve();
point = crv.getPointAt(length);
windMedian = PathItem._getWindingNumber(point, monoCurves);
v = crv.getValues();
horizontal = (Curve.isLinear(v) && abs(v[1] - v[7]) < tolerance);
// PathItem._getWindingNumber
windMedian = getWindingNumber(point, monoCurves, horizontal);
// While subtracting, we need to omit this curve if this
// curve is contributing to the second operand and is outside
// the first operand.

View file

@ -528,11 +528,10 @@ var PathItem = Item.extend(/** @lends PathItem# */{
* @return {Array} Array of contours traced.
*/
_tracePaths: function(segments, operator) {
var seg, nextSeg, startSeg, startSegIx, i, len, ixOther, j, prev,
var seg, nextSeg, startSeg, startSegIx, i, len, ixOther, prev,
ixOtherSeg, c1, c2, c3,
wind, w1, w3, s1, s3, path, nextHandleIn,
paths = [],
lenTolerance = 1;
paths = [];
for (i = 0, len = segments.length; i < len; i++) {
startSeg = seg = segments[i];
if (seg._visited || !operator(seg._winding))