Improve Line.intersect() to more reliably find interesctions at the beginnings / ends.

Relates to #784
This commit is contained in:
Jürg Lehni 2015-10-01 04:38:48 -05:00
parent 53ff973f06
commit 75a004187e
3 changed files with 19 additions and 8 deletions

View file

@ -133,14 +133,25 @@ var Line = Base.extend(/** @lends Line# */{
if (!Numerical.isZero(cross)) {
var dx = p1x - p2x,
dy = p1y - p2y,
t1 = (v2x * dy - v2y * dx) / cross,
t2 = (v1x * dy - v1y * dx) / cross;
u1 = (v2x * dy - v2y * dx) / cross,
u2 = (v1x * dy - v1y * dx) / cross,
// Compare the u values with EPSILON tolerance over the
// [0, 1] bounds.
uMin = -/*#=*/Numerical.EPSILON,
uMax = 1 + uMin;
// Check the ranges of t parameters if the line is not allowed
// to extend beyond the definition points.
if (isInfinite || 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1)
if (isInfinite
|| uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax) {
if (!isInfinite) {
// Address the tolerance at the bounds by clipping to
// the actual range.
u1 = u1 < 0 ? 0 : u1 > 1 ? 1 : u1;
}
return new Point(
p1x + t1 * v1x,
p1y + t1 * v1y);
p1x + u1 * v1x,
p1y + u1 * v1y);
}
}
},

View file

@ -1379,11 +1379,11 @@ new function() { // Scope for intersection using bezier fat-line clipping
// which connects back to the beginning, but only if it's not part of
// a found overlap. The normal intersection will already be found at
// the beginning, and would be added twice otherwise.
if (t1 >= (startConnected ? tMin : 0) &&
if (t1 !== null && t1 >= (startConnected ? tMin : 0) &&
t1 <= (endConnected ? tMax : 1)) {
if (t2 == null)
t2 = Curve.getParameterOf(v2, p2.x, p2.y);
if (t2 >= (endConnected ? tMin : 0) &&
if (t2 !== null && t2 >= (endConnected ? tMin : 0) &&
t2 <= (startConnected ? tMax : 1)) {
// TODO: Don't we need to check the range of t2 as well? Does it
// also need startConnected / endConnected values?

View file

@ -112,7 +112,7 @@ var Numerical = new function() {
KAPPA: 4 * (sqrt(2) - 1) / 3,
/**
* Check if the value is 0, within a tolerance defined by
* Checks if the value is 0, within a tolerance defined by
* Numerical.EPSILON.
*/
isZero: function(val) {