Bug fixes in the tracePath method to work with self-Intersection resolution

This commit is contained in:
hkrish 2014-02-02 22:36:00 +01:00
parent f8f31349d9
commit dfd1c97a4f

View file

@ -470,8 +470,11 @@ var PathItem = Item.extend(/** @lends PathItem# */{
// intersection, even when the curve[s] are linear. // intersection, even when the curve[s] are linear.
function getEntryExitTangents(seg) { function getEntryExitTangents(seg) {
var c2 = seg.getCurve(), var c2 = seg.getCurve(),
c1 = c2.getPrevious(), c1 = c2.getPrevious();
v1 = c1.getValues(), // Avoid zero length curves
c1 = c1.getLength() === 0 ? c1.getPrevious() : c1;
c2 = c2.getLength() === 0 ? c2.getNext() : c2;
var v1 = c1.getValues(),
v2 = c2.getValues(), v2 = c2.getValues(),
pnt = seg.getPoint(), pnt = seg.getPoint(),
ret = [seg.getHandleIn().normalize(), ret = [seg.getHandleIn().normalize(),
@ -504,8 +507,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{
firstHandleIn = null; firstHandleIn = null;
direction = 1; direction = 1;
// DEBUG:-------------------------------------------------------- // DEBUG:--------------------------------------------------------
// markPoint(seg, null, null, 2); // hilightCrvN("all");
// hilightCrv(seg.getCurve()); // hilightCrvN("next", seg.getCurve());
// DEBUG:-------------------------------------------------------- // DEBUG:--------------------------------------------------------
do { do {
nextHandleIn = direction > 0 ? seg._handleIn : seg._handleOut; nextHandleIn = direction > 0 ? seg._handleIn : seg._handleOut;
@ -516,9 +519,6 @@ var PathItem = Item.extend(/** @lends PathItem# */{
// else, stay on the same contour. // else, stay on the same contour.
if (ixOther && (ixOtherSeg = ixOther._segment) && if (ixOther && (ixOtherSeg = ixOther._segment) &&
ixOtherSeg !== startSeg && firstHandleIn) { ixOtherSeg !== startSeg && firstHandleIn) {
// DEBUG:--------------------------------------------------------
// markIx(seg);
// DEBUG:--------------------------------------------------------
entryExitTangents = getEntryExitTangents(seg); entryExitTangents = getEntryExitTangents(seg);
c1 = seg.getCurve(); c1 = seg.getCurve();
if (direction < 1) { if (direction < 1) {
@ -530,6 +530,9 @@ var PathItem = Item.extend(/** @lends PathItem# */{
entryExitTangents = getEntryExitTangents(ixOtherSeg); entryExitTangents = getEntryExitTangents(ixOtherSeg);
c4 = crvTan[1].c = ixOtherSeg.getCurve(); c4 = crvTan[1].c = ixOtherSeg.getCurve();
c3 = crvTan[0].c = c4.getPrevious(); c3 = crvTan[0].c = c4.getPrevious();
// Avoid zero length curves
c3 = crvTan[0].c = c3.getLength() === 0 ? c3.getPrevious() : c3;
c4 = crvTan[1].c = c4.getLength() === 0 ? c4.getNext() : c4;
crvTan[0].t = entryExitTangents[0]; crvTan[0].t = entryExitTangents[0];
crvTan[1].t = entryExitTangents[1]; crvTan[1].t = entryExitTangents[1];
// cross product of the entry and exit tangent vectors at // cross product of the entry and exit tangent vectors at
@ -539,26 +542,53 @@ var PathItem = Item.extend(/** @lends PathItem# */{
tan = crvTan[j].t; tan = crvTan[j].t;
crvTan[j].w = t1.x * tan.y - tan.x * t1.y; crvTan[j].w = t1.x * tan.y - tan.x * t1.y;
} }
// Do not attempt to switch contours if we not absolutely
// sure, that there is a possible candidate there.
if (crvTan[0].w * crvTan[1].w < 0) {
crvTan.sort(crvTanCompare); crvTan.sort(crvTanCompare);
j = 0; j = 0;
do { do {
crv = crvTan[j++].c; crv = crvTan[j++].c;
if (crv === c3) { if (crv === c3) {
nextSeg = c3.getSegment1(); nextSeg = c3.getSegment1();
// DEBUG:--------------------------------------------------------
// hilightCrvN("nextSeg", nextSeg, "#f00");
// hilightCrvN("nextCrv", c3, "#f00");
// DEBUG:--------------------------------------------------------
// Traverse backward // Traverse backward
direction = -1; direction = -1;
} else { } else {
nextSeg = crv.getSegment2(); nextSeg = c4.getSegment1();
// DEBUG:--------------------------------------------------------
// hilightCrvN("nextSeg", nextSeg, "#f00");
// hilightCrvN("nextCrv", c4, "#f00");
// DEBUG:--------------------------------------------------------
// Traverse forward // Traverse forward
direction = 1; direction = 1;
} }
} while (j < 2 && !operator(nextSeg._winding) || } while (j < 2 && !operator(nextSeg._winding) ||
(crv !== c3 && crv !== c4)); (crv !== c3 && crv !== c4));
} else {
nextSeg = null;
}
if (!nextSeg || !operator(nextSeg._winding)) {
direction = 1;
} else {
// Switch to the intersection segment. // Switch to the intersection segment.
seg._visited = ixOtherSeg._visited; seg._visited = ixOtherSeg._visited;
seg = ixOtherSeg; seg = ixOtherSeg;
if (nextSeg._visited)
direction = 1;
}
// DEBUG:--------------------------------------------------------
// hilightCrvN("nextCrv");
// hilightCrvN("nextSeg", nextSeg, "#0f0");
// DEBUG:--------------------------------------------------------
nextHandleOut = direction > 0 ? seg._handleOut : seg._handleIn; nextHandleOut = direction > 0 ? seg._handleOut : seg._handleIn;
} }
// DEBUG:--------------------------------------------------------
// hilightCrvN("next", seg.getCurve());
// DEBUG:--------------------------------------------------------
// Add the current segment to the path, and mark // Add the current segment to the path, and mark
// the added segment as visited // the added segment as visited
if (!firstHandleIn) { if (!firstHandleIn) {
@ -568,11 +598,13 @@ var PathItem = Item.extend(/** @lends PathItem# */{
path.add(new paper.Segment(seg._point, nextHandleIn, path.add(new paper.Segment(seg._point, nextHandleIn,
nextHandleOut)); nextHandleOut));
seg._visited = true; seg._visited = true;
// DEBUG:--------------------------------------------------------
// hilightCrv(direction ? seg.getCurve() : seg.getCurve().getPrevious(), true);
// DEBUG:--------------------------------------------------------
// Move to the next segment according to the traversal direction // Move to the next segment according to the traversal direction
seg = direction > 0 ? seg.getNext() : seg. getPrevious(); seg = direction > 0 ? seg.getNext() : seg. getPrevious();
// DEBUG:--------------------------------------------------------
// seg && hilightCrvN("next", direction ? seg.getCurve() : seg.getCurve().getPrevious(), "#a0a");
// DEBUG:--------------------------------------------------------
} while(seg && seg !== startSeg && seg !== startSegIx && } while(seg && seg !== startSeg && seg !== startSegIx &&
!seg._visited && (seg._intersection || operator(seg._winding))); !seg._visited && (seg._intersection || operator(seg._winding)));
// Finish with closing the paths if necessary, // Finish with closing the paths if necessary,
@ -595,6 +627,9 @@ var PathItem = Item.extend(/** @lends PathItem# */{
path.remove(); path.remove();
} }
} }
// DEBUG:--------------------------------------------------------
// hilightCrvN("all");
// DEBUG:--------------------------------------------------------
return paths; return paths;
}, },