mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-08 05:42:07 -05:00
Bug fixes in the tracePath method to work with self-Intersection resolution
This commit is contained in:
parent
f8f31349d9
commit
dfd1c97a4f
1 changed files with 62 additions and 27 deletions
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue