Improve debug logging and drawing.

And add more descriptive comments to tracePath().
This commit is contained in:
Jürg Lehni 2015-09-16 09:52:41 +02:00
parent 197aa4b4cf
commit f8bd7a2005
2 changed files with 40 additions and 20 deletions

View file

@ -282,7 +282,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
return curve && curve.split(this.getParameter(), true);
},
isCrossing: function(report) {
isCrossing: function(_report) {
// Implementation based on work by Andy Finnell:
// http://losingfight.com/blog/2011/07/09/how-to-implement-boolean-operations-on-bezier-paths-part-3/
// https://bitbucket.org/andyfinnell/vectorboolean
@ -303,7 +303,6 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
var tMin = /*#=*/Numerical.CURVETIME_EPSILON,
tMax = 1 - tMin,
PI = Math.PI,
PI_2 = PI * 2,
// TODO: Make getCurve() sync work in boolean ops after splitting!!!
c2 = this._curve,
c1 = c2.getPrevious(),
@ -311,7 +310,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
c3 = c4.getPrevious();
if (!c1 || !c3)
return this._crossing = false;
if (report) {
if (_report) {
new Path.Circle({
center: this.getPoint(),
radius: 10,
@ -325,13 +324,12 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
segments: [c3.getSegment1(), c3.getSegment2(), c4.getSegment2()],
strokeColor: 'orange'
});
console.log(c1.getValues(), c2.getValues(), c3.getValues(), c4.getValues());
}
function isInRange(angle, min, max) {
return min < max
? angle > min && angle < max
// The range wraps around 0:
// The range wraps around -PI / PI:
: angle > min && angle <= PI || angle >= -PI && angle < max;
}

View file

@ -149,8 +149,8 @@ PathItem.inject(new function() {
path1, path2);
}
var scaleFactor = 1; // 1 / 3000;
var textAngle = 60;
var scaleFactor = 0.25; // 1 / 3000;
var textAngle = 33;
var fontSize = 5;
/**
@ -543,36 +543,41 @@ PathItem.inject(new function() {
// resolving self-Intersections.
seg = other;
} else if (operation !== 'intersect' && inter._overlap) {
// Switch to the overlapping intersection segment
// if its winding number along the curve is 1, to
// leave the overlapping area.
// NOTE: We cannot check the next (overlapping)
// segment since its winding number will always be 2
drawSegment(seg, 'overlap', i, 'orange');
// Switch to the overlapping intersecting segment if its
// winding number along the curve is 1, meaning we leave the
// overlapping area.
// NOTE: We cannot check the next (overlapping) segment
// since its winding number will always be 2.
var curve = other.getCurve();
if (getWinding(curve.getPointAt(0.5, true),
monoCurves, curve.isHorizontal()) === 1) {
drawSegment(seg, 'overlap-cross', i, 'orange');
seg = other;
} else {
drawSegment(seg, 'overlap-stay', i, 'orange');
}
} else if (operation === 'exclude') {
// We need to handle exclusion separately, as we want to
// switch at each crossing, and at each intersection within
// the exclusion area even if it is not crossing.
// the exclusion area even if it is not a crossing.
if (inter.isCrossing() || path2.contains(seg._point)) {
seg = other;
drawSegment(seg, 'exclude-cross', i, 'green');
seg = other;
} else {
drawSegment(other, 'exclude-no-cross', i, 'orange');
drawSegment(seg, 'exclude-stay', i, 'orange');
}
} else if (operator(seg._winding)) {
// Do not switch to the intersecting segment as it is
// contained inside the boolean result.
// Do not switch to the intersecting segment as this segment
// is part of the the boolean result.
drawSegment(seg, 'ignore-keep', i, 'black');
} else if (operator(other._winding) && inter.isCrossing()) {
seg = other;
// The other segment is part of the boolean result, and we
// are at crossing, switch over.
drawSegment(seg, 'cross', i, 'green');
seg = other;
} else {
drawSegment(other, 'no-cross', i, 'orange');
// Keep on truckin'
drawSegment(seg, 'stay', i, 'orange');
}
if (seg._visited) {
// We didn't manage to switch, so stop right here.
@ -588,10 +593,27 @@ PathItem.inject(new function() {
seg = seg.getNext();
inter = seg && seg._intersection;
other = inter && inter._segment;
if (seg === start || seg === otherStart) {
drawSegment(seg, 'close', i, 'red');
}
if (seg._visited && (!other || other._visited)) {
drawSegment(seg, 'visited', i, 'red');
}
if (!inter && !operator(seg._winding)) {
// TODO: We really should find a way to go backwards perhaps
// and try another path when this happens?
drawSegment(seg, 'discard', i, 'red');
console.error('Excluded segment encountered, aborting #'
+ pathCount + '.' +
(path ? path._segments.length + 1 : 1));
}
} while (seg && seg !== start && seg !== otherStart
// If we're about to switch, try to see if we can carry on
// if the other segment wasn't visited yet.
&& (!seg._visited || other && !other._visited)
// Intersections are always part of the resulting path, for
// all other segments check the winding contribution to see
// if they are to be kept. If not, the chain has to end here
&& (inter || operator(seg._winding)));
// Finish with closing the paths if necessary, correctly linking up
// curves etc.