Fix various issues introduced in #1740

This commit is contained in:
Jürg Lehni 2019-12-13 16:13:56 +01:00
parent 1f39b1df98
commit a183dc0c0d
2 changed files with 34 additions and 34 deletions

View file

@ -161,7 +161,7 @@ PathItem.inject(new function() {
for (var i = 0, l = curves.length; i < l; i++) { for (var i = 0, l = curves.length; i < l; i++) {
curvesValues[i] = curves[i].getValues(); curvesValues[i] = curves[i].getValues();
} }
var horCurveCollisions = var horCurveCollisions =
CollisionDetection.findCurveBoundsCollisions( CollisionDetection.findCurveBoundsCollisions(
curvesValues, curvesValues, 0, false, true); curvesValues, curvesValues, 0, false, true);
var horCurvesMap = {}; var horCurvesMap = {};
@ -179,7 +179,7 @@ PathItem.inject(new function() {
horCurvesMap[pathId][curve.getIndex()] = collidingCurves; horCurvesMap[pathId][curve.getIndex()] = collidingCurves;
} }
var vertCurveCollisions = var vertCurveCollisions =
CollisionDetection.findCurveBoundsCollisions( CollisionDetection.findCurveBoundsCollisions(
curvesValues, curvesValues, 0, true, true); curvesValues, curvesValues, 0, true, true);
var vertCurvesMap = {}; var vertCurvesMap = {};
@ -202,14 +202,14 @@ PathItem.inject(new function() {
// First, propagate winding contributions for curve chains starting // First, propagate winding contributions for curve chains starting
// in all crossings: // in all crossings:
for (var i = 0, l = crossings.length; i < l; i++) { for (var i = 0, l = crossings.length; i < l; i++) {
propagateWinding(crossings[i]._segment, _path1, _path2, propagateWinding(crossings[i]._segment, _path1, _path2,
horCurvesMap, vertCurvesMap, operator); horCurvesMap, vertCurvesMap, operator);
} }
for (var i = 0, l = segments.length; i < l; i++) { for (var i = 0, l = segments.length; i < l; i++) {
var segment = segments[i], var segment = segments[i],
inter = segment._intersection; inter = segment._intersection;
if (!segment._winding) { if (!segment._winding) {
propagateWinding(segment, _path1, _path2, propagateWinding(segment, _path1, _path2,
horCurvesMap, vertCurvesMap, operator); horCurvesMap, vertCurvesMap, operator);
} }
// See if all encountered segments in a path are overlaps. // See if all encountered segments in a path are overlaps.
@ -349,16 +349,16 @@ PathItem.inject(new function() {
// Now determine the winding for each path, from large to small. // Now determine the winding for each path, from large to small.
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
var path1 = sorted[i], var path1 = sorted[i],
indicesI = collisions[i]; indicesI = collisions[i],
entry1 = lookup[path1._id],
containerWinding = 0;
if (indicesI) { if (indicesI) {
var entry1 = lookup[path1._id], var point = null; // interior point, only get it if required
point = null; // interior point, only get it if required
containerWinding = 0;
for (var j = indicesI.length - 1; j >= 0; j--) { for (var j = indicesI.length - 1; j >= 0; j--) {
if (indicesI[j] < i) { if (indicesI[j] < i) {
point = point || path1.getInteriorPoint(); point = point || path1.getInteriorPoint();
var path2 = sorted[indicesI[j]]; var path2 = sorted[indicesI[j]];
// As we run through the paths from largest to // As we run through the paths from largest to
// smallest, for any current path, all potentially // smallest, for any current path, all potentially
// containing paths have already been processed and // containing paths have already been processed and
// their orientation fixed. To achieve correct // their orientation fixed. To achieve correct
@ -369,7 +369,7 @@ PathItem.inject(new function() {
var entry2 = lookup[path2._id]; var entry2 = lookup[path2._id];
containerWinding = entry2.winding; containerWinding = entry2.winding;
entry1.winding += containerWinding; entry1.winding += containerWinding;
entry1.container = entry2.exclude ? entry1.container = entry2.exclude ?
entry2.container : path2; entry2.container : path2;
break; break;
} }
@ -865,7 +865,7 @@ PathItem.inject(new function() {
var curveIndex = curve.getIndex(); var curveIndex = curve.getIndex();
var hCollisions = horCurveCollisionsMap[pathId][curveIndex]; var hCollisions = horCurveCollisionsMap[pathId][curveIndex];
var vCollisions = vertCurveCollisionsMap[pathId][curveIndex]; var vCollisions = vertCurveCollisionsMap[pathId][curveIndex];
wind = wind || wind = wind ||
getWinding(pt, hCollisions, vCollisions, dir, true); getWinding(pt, hCollisions, vCollisions, dir, true);
if (wind.quality > winding.quality) if (wind.quality > winding.quality)
winding = wind; winding = wind;
@ -1142,7 +1142,7 @@ PathItem.inject(new function() {
* @return {Number} the winding number * @return {Number} the winding number
*/ */
_getWinding: function(point, dir, closed) { _getWinding: function(point, dir, closed) {
let curves = this.getCurves(); var curves = this.getCurves();
return getWinding(point, curves, curves, dir, closed); return getWinding(point, curves, curves, dir, closed);
}, },

View file

@ -19,12 +19,12 @@ var CollisionDetection = /** @lends CollisionDetection */{
/** /**
* Finds collisions between axis aligned bounding boxes of items. * Finds collisions between axis aligned bounding boxes of items.
* *
* This function takes the bounds of all items in the items1 and items2 * This function takes the bounds of all items in the items1 and items2
* arrays and calls findBoundsCollisions(). * arrays and calls findBoundsCollisions().
* *
* @param {Array} itemsA Array of curve values for which collisions should * @param {Array} itemsA Array of curve values for which collisions should
* be found. * be found.
* @param {Array} [itemsA] Array of curve values that the first array should * @param {Array} [itemsA] Array of curve values that the first array should
* be compared with. If not provided, collisions between items within * be compared with. If not provided, collisions between items within
* the first arrray will be returned. * the first arrray will be returned.
@ -74,7 +74,7 @@ var CollisionDetection = /** @lends CollisionDetection */{
* curveValues1 and curveValues2 arrays and calls findBoundsCollisions(). * curveValues1 and curveValues2 arrays and calls findBoundsCollisions().
* *
* @param {Array} curvesValues1 Array of curve values for which collisions * @param {Array} curvesValues1 Array of curve values for which collisions
* should be found. * should be found.
* @param {Array} [curvesValues2] Array of curve values that the first * @param {Array} [curvesValues2] Array of curve values that the first
* array should be compared with. If not provided, collisions between * array should be compared with. If not provided, collisions between
* curve bounds within the first arrray will be returned. * curve bounds within the first arrray will be returned.
@ -127,26 +127,26 @@ var CollisionDetection = /** @lends CollisionDetection */{
/** /**
* Finds collisions between two sets of bounding rectangles. * Finds collisions between two sets of bounding rectangles.
* *
* The collision detection is implemented as a sweep and prune algorithm * The collision detection is implemented as a sweep and prune algorithm
* with sweep either along the x or y axis (primary axis) and immediate * with sweep either along the x or y axis (primary axis) and immediate
* check on secondary axis for potential pairs. * check on secondary axis for potential pairs.
* *
* Each entry in the bounds arrays must be an array of length 4 with * Each entry in the bounds arrays must be an array of length 4 with
* x0, y0, x1, and y1 as the array elements. * x0, y0, x1, and y1 as the array elements.
* *
* The returned array has the same length as boundsArr1. Each entry * The returned array has the same length as boundsArr1. Each entry
* contains an array with all indices of overlapping bounds of * contains an array with all indices of overlapping bounds of
* boundsArr2 (or boundsArr1 if boundsArr2 is not provided) sorted * boundsArr2 (or boundsArr1 if boundsArr2 is not provided) sorted
* in ascending order. * in ascending order.
* *
* If the second bounds array parameter is null, collisions between bounds * If the second bounds array parameter is null, collisions between bounds
* within the first bounds array will be found. In this case the indexed * within the first bounds array will be found. In this case the indexed
* returned for each bounds will not contain the bounds' own index. * returned for each bounds will not contain the bounds' own index.
* *
* *
* @param {Array} boundsArr1 Array of bounds objects for which collisions * @param {Array} boundsArr1 Array of bounds objects for which collisions
* should be found. * should be found.
* @param {Array} [boundsArr2] Array of bounds that the first array should * @param {Array} [boundsArr2] Array of bounds that the first array should
* be compared with. If not provided, collisions between bounds within * be compared with. If not provided, collisions between bounds within
* the first arrray will be returned. * the first arrray will be returned.
@ -159,15 +159,20 @@ var CollisionDetection = /** @lends CollisionDetection */{
* @returns {Array} Array containing for the bounds at thes same index in * @returns {Array} Array containing for the bounds at thes same index in
* boundsA an array of the indexes of colliding bounds in boundsB * boundsA an array of the indexes of colliding bounds in boundsB
* *
* @author Jan Boesenberg <jan.boesenberg@gmail.com> * @author Jan Boesenberg <jan.boesenberg@gmail.com>
*/ */
findBoundsCollisions: function(boundsA, boundsB, tolerance, findBoundsCollisions: function(boundsA, boundsB, tolerance,
sweepVertical, onlySweepAxisCollisions) { sweepVertical, onlySweepAxisCollisions) {
// Binary search utility function. // Binary search utility function.
// For multiple same entries, this returns the rightmost entry. // For multiple same entries, this returns the rightmost entry.
// https://en.wikipedia.org/wiki/Binary_search_algorithm#Procedure_for_finding_the_rightmost_element // https://en.wikipedia.org/wiki/Binary_search_algorithm#Procedure_for_finding_the_rightmost_element
var lo, hi; var self = !boundsB || boundsA === boundsB,
var binarySearch = function(indices, coordinateValue, coordinate) { allBounds = self ? boundsA : boundsA.concat(boundsB),
countA = boundsA.length,
countAll = allBounds.length,
lo, hi;
function binarySearch(indices, coordinateValue, coordinate) {
lo = 0; lo = 0;
hi = indices.length; hi = indices.length;
while (lo < hi) { while (lo < hi) {
@ -179,13 +184,8 @@ var CollisionDetection = /** @lends CollisionDetection */{
} }
} }
return lo - 1; return lo - 1;
}; }
//
var self = !boundsB || boundsA === boundsB,
allBounds = self ? boundsA : boundsA.concat(boundsB),
countA = boundsA.length,
countAll = allBounds.length;
// Set coordinates for primary and secondary axis depending on sweep // Set coordinates for primary and secondary axis depending on sweep
// direction. By default we sweep in horizontal direction, which // direction. By default we sweep in horizontal direction, which
// means x is the primary axis. // means x is the primary axis.
@ -208,7 +208,7 @@ var CollisionDetection = /** @lends CollisionDetection */{
allCollisions = new Array(countA); allCollisions = new Array(countA);
for (var i = 0; i < countAll; i++) { for (var i = 0; i < countAll; i++) {
var currentIndex = allIndicesByP0[i], var currentIndex = allIndicesByP0[i],
currentBounds = allBounds[currentIndex]; currentBounds = allBounds[currentIndex],
currentOriginalIndex = self ? currentIndex currentOriginalIndex = self ? currentIndex
: currentIndex - countA, // index in boundsA or boundsB array : currentIndex - countA, // index in boundsA or boundsB array
isCurrentA = currentIndex < countA, isCurrentA = currentIndex < countA,
@ -279,7 +279,7 @@ var CollisionDetection = /** @lends CollisionDetection */{
activeIndicesByP1.push(currentIndex); activeIndicesByP1.push(currentIndex);
} }
} }
// Sort collision indioes in ascending order // Sort collision indices in ascending order
for (var i = 0; i < allCollisions.length; i++) { for (var i = 0; i < allCollisions.length; i++) {
if (allCollisions[i]) { if (allCollisions[i]) {
allCollisions[i].sort(function(i1, i2) { allCollisions[i].sort(function(i1, i2) {
@ -289,4 +289,4 @@ var CollisionDetection = /** @lends CollisionDetection */{
} }
return allCollisions; return allCollisions;
} }
}; };