mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Improve debug logging and drawing.
And add more descriptive comments to tracePath().
This commit is contained in:
parent
197aa4b4cf
commit
f8bd7a2005
2 changed files with 40 additions and 20 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue