Improve reliability of Curve#isStraight()

Closes #1066
This commit is contained in:
Jürg Lehni 2016-06-10 12:33:44 +02:00
parent 1f4e4f2f60
commit 803dfb6bb1
2 changed files with 38 additions and 13 deletions

View file

@ -881,22 +881,29 @@ statics: /** @lends Curve */{
if (h1.isZero() && h2.isZero()) {
// No handles.
return true;
} else if (l.isZero()) {
// Zero-length line, with some handles defined.
return false;
} else if (h1.isCollinear(l) && h2.isCollinear(l)) {
// Collinear handles. Project them onto line to see if they are
// within the line's range:
var div = l.dot(l),
p1 = l.dot(h1) / div,
p2 = l.dot(h2) / div;
return p1 >= 0 && p1 <= 1 && p2 <= 0 && p2 >= -1;
} else {
var v = l.getVector(),
epsilon = /*#=*/Numerical.GEOMETRIC_EPSILON;
if (v.isZero()) {
// Zero-length line, with some handles defined.
return false;
} else if (l.getDistance(h1) < epsilon
&& l.getDistance(h2) < epsilon) {
// Collinear handles: Instead of v.isCollinear(h1) checks, we
// need to measure the distance to the line, in order to be able
// to use the same epsilon as in Curve#getTimeOf(), see #1066.
// Project them onto line to see if they are within its range:
var div = v.dot(v),
p1 = v.dot(h1) / div,
p2 = v.dot(h2) / div;
return p1 >= 0 && p1 <= 1 && p2 <= 0 && p2 >= -1;
}
}
return false;
},
isLinear: function(l, h1, h2) {
var third = l.divide(3);
var third = l.getVector().divide(3);
return h1.equals(third) && h2.negate().equals(third);
}
}, function(test, name) {
@ -904,7 +911,7 @@ statics: /** @lends Curve */{
this[name] = function() {
var seg1 = this._segment1,
seg2 = this._segment2;
return test(seg2._point.subtract(seg1._point),
return test(new Line(seg1._point, seg2._point),
seg1._handleOut, seg2._handleIn);
};
@ -912,7 +919,7 @@ statics: /** @lends Curve */{
this.statics[name] = function(v) {
var p1x = v[0], p1y = v[1],
p2x = v[6], p2y = v[7];
return test(new Point(p2x - p1x, p2y - p1y),
return test(new Line(p1x, p1y, p2x, p2y),
new Point(v[2] - p1x, v[3] - p1y),
new Point(v[4] - p2x, v[5] - p2y));
};

View file

@ -103,3 +103,21 @@ test('circle and square (existing segments overlaps on curves)', function() {
{ point: { x: 110, y: 190 }, index: 3, time: 0, crossing: true }
]);
});
test('#1066', function() {
var path1 = new paper.Path({
segments: [
[230.4447915660904, 300],
[230.4447915660904, 180]
]
});
var path2 = new paper.Path({
segments: [
[221.5842044289023, 189.47264666691018, 0, 0, 9.363067822501023, 28.089207003036847],
[249.67341143193917, 273.74026767602066, -9.363067822501023, -28.08920700303679, 0, 0]
]
});
testIntersection(path1.getIntersections(path2), [
{ point: { x: 230.44479, y: 216.05441 }, index: 0, time: 0.63642, crossing: true }
]);
});