mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-22 07:19:57 -05:00
Revert "Substantial simplifications in boolean code."
This reverts commit a665175a89
.
This commit is contained in:
parent
7aef20ae6b
commit
5e327f7a48
1 changed files with 59 additions and 15 deletions
|
@ -531,33 +531,53 @@ PathItem.inject(new function() {
|
||||||
inter = seg._intersection,
|
inter = seg._intersection,
|
||||||
otherSeg = inter && inter._segment,
|
otherSeg = inter && inter._segment,
|
||||||
otherStartSeg = otherSeg,
|
otherStartSeg = otherSeg,
|
||||||
added = false; // Whether a first segment as added already
|
added = false, // Whether a first segment as added already
|
||||||
|
dir = 1;
|
||||||
do {
|
do {
|
||||||
var handleIn = added && seg._handleIn;
|
var handleIn = dir > 0 ? seg._handleIn : seg._handleOut,
|
||||||
|
handleOut = dir > 0 ? seg._handleOut : seg._handleIn;
|
||||||
// If the intersection segment is valid, try switching to
|
// If the intersection segment is valid, try switching to
|
||||||
// it, with an appropriate direction to continue traversal.
|
// it, with an appropriate direction to continue traversal.
|
||||||
// Else, stay on the same contour.
|
// Else, stay on the same contour.
|
||||||
if (added && otherSeg && otherSeg !== startSeg) {
|
if (added && otherSeg && otherSeg !== startSeg) {
|
||||||
if (otherSeg._path === seg._path) { // Self-intersection
|
if (otherSeg._path === seg._path) { // Self-intersection
|
||||||
drawSegment(seg, 'self-int', i, 'red');
|
drawSegment(seg, 'self-int ' + dir, i, 'red');
|
||||||
// Switch to the intersection segment, as we need to
|
// Switch to the intersection segment, as we need to
|
||||||
// resolving self-Intersections.
|
// resolving self-Intersections.
|
||||||
seg = otherSeg;
|
seg = otherSeg;
|
||||||
} else if (operation !== 'exclude' && operator(seg._winding)) {
|
dir = 1;
|
||||||
|
} else if (operator(seg._winding)) {
|
||||||
|
// We need to handle exclusion separately and switch on
|
||||||
|
// every intersection that's part of the result.
|
||||||
|
if (operation === 'exclude') {
|
||||||
|
// Look at the crossing tangents to decide whether
|
||||||
|
// to switch over or not.
|
||||||
|
var t1 = seg.getCurve().getTangentAt(tMin, true),
|
||||||
|
t2 = otherSeg.getCurve().getTangentAt(tMin, true);
|
||||||
|
if (Math.abs(t1.cross(t2)) > epsilon) {
|
||||||
|
seg = otherSeg;
|
||||||
|
drawSegment(seg, 'exclude:switch', i, 'green');
|
||||||
|
dir = 1;
|
||||||
|
} else {
|
||||||
|
drawSegment(seg, 'exclude:no cross', i, 'blue');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Do not switch to the intersection as the segment
|
// Do not switch to the intersection as the segment
|
||||||
// is part of the boolean result.
|
// is part of the boolean result.
|
||||||
drawSegment(seg, 'keep', i, 'black');
|
drawSegment(seg, 'keep', i, 'black');
|
||||||
} else if (operation !== 'intersect' && inter._overlap) {
|
}
|
||||||
|
} else if (inter._overlap && operation !== 'intersect') {
|
||||||
// Switch to the overlapping intersection segment
|
// Switch to the overlapping intersection segment
|
||||||
// if its winding number along the curve is 1, to
|
// if its winding number along the curve is 1, to
|
||||||
// leave the overlapping area.
|
// leave the overlapping area.
|
||||||
// NOTE: We cannot check the next (overlapping)
|
// NOTE: We cannot check the next (overlapping)
|
||||||
// segment since its winding number will always be 2
|
// segment since its winding number will always be 2
|
||||||
drawSegment(seg, 'overlap', i, 'orange');
|
drawSegment(seg, 'overlap ' + dir, i, 'orange');
|
||||||
var curve = otherSeg.getCurve();
|
var curve = otherSeg.getCurve();
|
||||||
if (getWinding(curve.getPointAt(0.5, true),
|
if (getWinding(curve.getPointAt(0.5, true),
|
||||||
monoCurves, curve.isHorizontal()) === 1) {
|
monoCurves, curve.isHorizontal()) === 1) {
|
||||||
seg = otherSeg;
|
seg = otherSeg;
|
||||||
|
dir = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var t = seg.getCurve().getTangentAt(tMin, true),
|
var t = seg.getCurve().getTangentAt(tMin, true),
|
||||||
|
@ -567,27 +587,51 @@ PathItem.inject(new function() {
|
||||||
c1 = c2.getPrevious(),
|
c1 = c2.getPrevious(),
|
||||||
// Calculate their winding values and tangents.
|
// Calculate their winding values and tangents.
|
||||||
t1 = c1.getTangentAt(tMax, true),
|
t1 = c1.getTangentAt(tMax, true),
|
||||||
t2 = c2.getTangentAt(tMin, true);
|
t2 = c2.getTangentAt(tMin, true),
|
||||||
// Cross product of the entry and exit tangent
|
// Cross product of the entry and exit tangent
|
||||||
// vectors at the intersection, will let us select
|
// vectors at the intersection, will let us select
|
||||||
// the correct contour to traverse next.
|
// the correct contour to traverse next.
|
||||||
if (Math.abs(t.cross(t1) * t.cross(t2)) > epsilon) {
|
w1 = t.cross(t1),
|
||||||
|
w2 = t.cross(t2);
|
||||||
|
if (Math.abs(w1 * w2) > epsilon) {
|
||||||
|
// Do not attempt to switch contours if we aren't
|
||||||
|
// sure that there is a possible candidate.
|
||||||
|
var curve = w1 < w2 ? c1 : c2,
|
||||||
|
nextCurve = operator(curve._segment1._winding)
|
||||||
|
? curve
|
||||||
|
: w1 < w2 ? c2 : c1,
|
||||||
|
nextSeg = nextCurve._segment1;
|
||||||
|
dir = nextCurve === c1 ? -1 : 1;
|
||||||
|
// If we didn't find a suitable direction for next
|
||||||
|
// contour to traverse, stay on the same contour.
|
||||||
|
if (nextSeg._visited && seg._path !== nextSeg._path
|
||||||
|
|| !operator(nextSeg._winding)) {
|
||||||
|
drawSegment(nextSeg, 'not suitable', i, 'orange');
|
||||||
|
dir = 1;
|
||||||
|
} else {
|
||||||
|
// Switch to the intersection segment.
|
||||||
seg = otherSeg;
|
seg = otherSeg;
|
||||||
|
// TODO: Find a case that actually requires this
|
||||||
|
if (nextSeg._visited)
|
||||||
|
dir = 1;
|
||||||
drawSegment(seg, 'switch', i, 'green');
|
drawSegment(seg, 'switch', i, 'green');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
drawSegment(seg, 'no cross', i, 'blue');
|
drawSegment(seg, 'no cross', i, 'blue');
|
||||||
|
dir = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handleOut = dir > 0 ? seg._handleOut : seg._handleIn;
|
||||||
} else {
|
} else {
|
||||||
drawSegment(seg, 'keep', i, 'black');
|
drawSegment(seg, 'keep', i, 'black');
|
||||||
}
|
}
|
||||||
// Add the current segment to the path, and mark the added
|
// Add the current segment to the path, and mark the added
|
||||||
// segment as visited.
|
// segment as visited.
|
||||||
path.add(new Segment(seg._point, handleIn, seg._handleOut));
|
path.add(new Segment(seg._point, added && handleIn, handleOut));
|
||||||
seg._visited = true;
|
seg._visited = true;
|
||||||
added = true;
|
added = true;
|
||||||
// Move to the next segment according to the traversal direction
|
// Move to the next segment according to the traversal direction
|
||||||
seg = seg.getNext();
|
seg = dir > 0 ? seg.getNext() : seg. getPrevious();
|
||||||
inter = seg && seg._intersection;
|
inter = seg && seg._intersection;
|
||||||
otherSeg = inter && inter._segment;
|
otherSeg = inter && inter._segment;
|
||||||
if (window.reportSegments) {
|
if (window.reportSegments) {
|
||||||
|
|
Loading…
Reference in a new issue