mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-06 04:42:15 -05:00
Properly solve issues with self-intersecting special case.
(e.g. shapes resembling the infinity sign)
This commit is contained in:
parent
fc0b5a8858
commit
fd927cbe22
3 changed files with 27 additions and 23 deletions
|
@ -1040,7 +1040,7 @@ statics: {
|
|||
step /= 2;
|
||||
}
|
||||
var pt = Curve.getPoint(values, minT);
|
||||
return new CurveLocation(this, minT, pt, point.getDistance(pt));
|
||||
return new CurveLocation(this, minT, pt, null, point.getDistance(pt));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1357,11 +1357,10 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
|||
|
||||
function addLocation(locations, param, v1, c1, t1, p1, v2, c2, t2, p2,
|
||||
overlap) {
|
||||
var loc = null,
|
||||
var startConnected = param.startConnected,
|
||||
endConnected = param.endConnected,
|
||||
tMin = /*#=*/Numerical.CURVETIME_EPSILON,
|
||||
tMax = 1 - tMin,
|
||||
startConnected = param.startConnected,
|
||||
endConnected = param.endConnected;
|
||||
tMax = 1 - tMin;
|
||||
if (t1 == null)
|
||||
t1 = Curve.getParameterOf(v1, p1.x, p1.y);
|
||||
// Check t1 and t2 against correct bounds, based on start-/endConnected:
|
||||
|
@ -1372,11 +1371,11 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
|||
// a found overlap. The normal intersection will already be found at
|
||||
// the beginning, and would be added twice otherwise.
|
||||
if (t1 >= (startConnected ? tMin : 0) &&
|
||||
t1 <= (endConnected || !overlap && c1.isLast() ? tMax : 1)) {
|
||||
t1 <= (endConnected ? tMax : 1)) {
|
||||
if (t2 == null)
|
||||
t2 = Curve.getParameterOf(v2, p2.x, p2.y);
|
||||
if (t2 >= (endConnected ? tMin : 0) &&
|
||||
t2 <= (startConnected || !overlap && c2.isLast() ? tMax : 1)) {
|
||||
t2 <= (startConnected ? tMax : 1)) {
|
||||
// TODO: Don't we need to check the range of t2 as well? Does it
|
||||
// also need startConnected / endConnected values?
|
||||
var renormalize = param.renormalize;
|
||||
|
@ -1385,13 +1384,25 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
|||
t1 = res[0];
|
||||
t2 = res[1];
|
||||
}
|
||||
var include = param.include,
|
||||
loc = new CurveLocation(c1, t1,
|
||||
p1 || Curve.getPoint(v1, t1), null, overlap,
|
||||
new CurveLocation(c2, t2,
|
||||
p2 || Curve.getPoint(v2, t2), null, overlap));
|
||||
if (!include || include(loc))
|
||||
var loc1 = new CurveLocation(c1, t1,
|
||||
p1 || Curve.getPoint(v1, t1), overlap),
|
||||
loc2 = new CurveLocation(c2, t2,
|
||||
p2 || Curve.getPoint(v2, t2), overlap),
|
||||
// For self-intersections, detect the case where the second
|
||||
// curve wrapped around, and flip them so they can get
|
||||
// matched to a potentially already existing intersection.
|
||||
flip = loc1.getPath() === loc2.getPath()
|
||||
&& loc1.getIndex() > loc2.getIndex(),
|
||||
loc = flip ? loc2 : loc1,
|
||||
include = param.include;
|
||||
// Link the two locations to each other.
|
||||
loc1._intersection = loc2;
|
||||
loc2._intersection = loc1;
|
||||
// TODO: Remove this once debug logging is removed.
|
||||
(flip ? loc1 : loc2)._other = true;
|
||||
if (!include || include(loc)) {
|
||||
CurveLocation.add(locations, loc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
* @param {Point} [point]
|
||||
*/
|
||||
initialize: function CurveLocation(curve, parameter, point,
|
||||
_distance, _overlap, _intersection) {
|
||||
_overlap, _distance) {
|
||||
// Merge intersections very close to the end of a curve to the
|
||||
// beginning of the next curve.
|
||||
if (parameter >= 1 - /*#=*/Numerical.CURVETIME_EPSILON) {
|
||||
|
@ -60,15 +60,9 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
this._setCurve(curve);
|
||||
this._parameter = parameter;
|
||||
this._point = point || curve.getPointAt(parameter, true);
|
||||
this._distance = _distance;
|
||||
this._overlap = _overlap;
|
||||
this._crossing = null;
|
||||
this._intersection = _intersection;
|
||||
if (_intersection) {
|
||||
_intersection._intersection = this;
|
||||
// TODO: Remove this once debug logging is removed.
|
||||
_intersection._other = true;
|
||||
}
|
||||
this._distance = _distance;
|
||||
this._intersection = null;
|
||||
},
|
||||
|
||||
_setCurve: function(curve) {
|
||||
|
|
|
@ -639,7 +639,6 @@ PathItem.inject(new function() {
|
|||
if (added && (seg === start || seg === otherStart)) {
|
||||
// We've come back to the start, bail out as we're done.
|
||||
drawSegment(seg, null, 'done', i, 'red');
|
||||
seg._visited = true;
|
||||
break;
|
||||
} else if (seg._visited && (!other || other._visited)) {
|
||||
// TODO: Do we still need to check other too?
|
||||
|
|
Loading…
Reference in a new issue