mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -05:00
Improve and clean up fat-line bug fix.
This commit is contained in:
parent
38f31be6b2
commit
01e48b3322
5 changed files with 30 additions and 36 deletions
|
@ -485,7 +485,7 @@ function testIntersections(path1, path2, caption, testname, testdata, nomark) {
|
||||||
fatTime: t2,
|
fatTime: t2,
|
||||||
success: success
|
success: success
|
||||||
});
|
});
|
||||||
console.log(found);
|
console.log(ixsPaper.length, found);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
var ser = new XMLSerializer();
|
var ser = new XMLSerializer();
|
||||||
console.log('failcase:', ser.serializeToString(path1.exportSVG()),
|
console.log('failcase:', ser.serializeToString(path1.exportSVG()),
|
||||||
|
|
|
@ -19,6 +19,6 @@ var options = {
|
||||||
browser: true,
|
browser: true,
|
||||||
stats: true,
|
stats: true,
|
||||||
svg: true,
|
svg: true,
|
||||||
fatline: false,
|
fatline: true,
|
||||||
debug: false
|
debug: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -869,7 +869,7 @@ statics: {
|
||||||
step /= 2;
|
step /= 2;
|
||||||
}
|
}
|
||||||
var pt = Curve.evaluate(values, minT, true, 0);
|
var pt = Curve.evaluate(values, minT, true, 0);
|
||||||
return new CurveLocation(this, minT, pt, null, null,
|
return new CurveLocation(this, minT, pt, null, null, null,
|
||||||
point.getDistance(pt));
|
point.getDistance(pt));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -966,7 +966,7 @@ new function() { // Scope for methods that require numerical integration
|
||||||
a = 0;
|
a = 0;
|
||||||
if (b === undefined)
|
if (b === undefined)
|
||||||
b = 1;
|
b = 1;
|
||||||
// if (p1 == c1 && p2 == c2):
|
// See if the curve is linear by checking p1 == c1 and p2 == c2
|
||||||
if (v[0] == v[2] && v[1] == v[3] && v[6] == v[4] && v[7] == v[5]) {
|
if (v[0] == v[2] && v[1] == v[3] && v[6] == v[4] && v[7] == v[5]) {
|
||||||
// Straight line
|
// Straight line
|
||||||
var dx = v[6] - v[0], // p2x - p1x
|
var dx = v[6] - v[0], // p2x - p1x
|
||||||
|
@ -1030,13 +1030,14 @@ new function() { // Scope for methods that require numerical integration
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, new function() { // Scope for intersection using bezier fat-line clipping
|
}, new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
function addLocation(locations, curve1, t1, point, curve2, t2) {
|
function addLocation(locations, curve1, t1, point1, curve2, t2, point2) {
|
||||||
// Avoid duplicates when hitting segments (closed paths too)
|
// Avoid duplicates when hitting segments (closed paths too)
|
||||||
var first = locations[0],
|
var first = locations[0],
|
||||||
last = locations[locations.length - 1];
|
last = locations[locations.length - 1];
|
||||||
if ((!first || !point.equals(first._point))
|
if ((!first || !point1.equals(first._point))
|
||||||
&& (!last || !point.equals(last._point)))
|
&& (!last || !point1.equals(last._point)))
|
||||||
locations.push(new CurveLocation(curve1, t1, point, curve2, t2));
|
locations.push(
|
||||||
|
new CurveLocation(curve1, t1, point1, curve2, t2, point2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCurveIntersections(v1, v2, curve1, curve2, locations,
|
function addCurveIntersections(v1, v2, curve1, curve2, locations,
|
||||||
|
@ -1065,9 +1066,7 @@ new function() { // Scope for methods that require numerical integration
|
||||||
// degenerate case seperately, where fat-line clipping can become
|
// degenerate case seperately, where fat-line clipping can become
|
||||||
// numerically unstable when one of the curves has converged to a point
|
// numerically unstable when one of the curves has converged to a point
|
||||||
// and the other hasn't.
|
// and the other hasn't.
|
||||||
while (iteration++ < 20
|
while (iteration++ < 20) {
|
||||||
&& (Math.abs(range1[1] - range1[0]) > /*#=*/ Numerical.TOLERANCE
|
|
||||||
|| Math.abs(range2[1] - range2[0]) > /*#=*/ Numerical.TOLERANCE)) {
|
|
||||||
// First we clip v2 with v1's fat-line
|
// First we clip v2 with v1's fat-line
|
||||||
var range,
|
var range,
|
||||||
intersects1 = clipFatLine(part1, part2, range = range2.slice()),
|
intersects1 = clipFatLine(part1, part2, range = range2.slice()),
|
||||||
|
@ -1119,14 +1118,15 @@ new function() { // Scope for methods that require numerical integration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We need to bailout of clipping and try a numerically stable
|
// We need to bailout of clipping and try a numerically stable
|
||||||
// method if both of the parameter ranges have converged reasonably well
|
// method if both of the parameter ranges have converged reasonably
|
||||||
// (according to Numerical.TOLERANCE).
|
// well (according to Numerical.TOLERANCE).
|
||||||
if (Math.abs(range1[1] - range1[0]) < /*#=*/ Numerical.TOLERANCE &&
|
if (Math.abs(range1[1] - range1[0]) <= /*#=*/ Numerical.TOLERANCE &&
|
||||||
Math.abs(range2[1] - range2[0]) < /*#=*/ Numerical.TOLERANCE) {
|
Math.abs(range2[1] - range2[0]) <= /*#=*/ Numerical.TOLERANCE) {
|
||||||
var t1 = (range1[0] + range1[1]) / 2,
|
var t1 = (range1[0] + range1[1]) / 2,
|
||||||
t2 = (range2[0] + range2[1]) / 2;
|
t2 = (range2[0] + range2[1]) / 2;
|
||||||
addLocation(locations, curve1, t1,
|
addLocation(locations,
|
||||||
Curve.evaluate(v1, t1, true, 0), curve2, t2);
|
curve1, t1, Curve.evaluate(v1, t1, true, 0),
|
||||||
|
curve2, t2, Curve.evaluate(v2, t2, true, 0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1330,10 +1330,9 @@ new function() { // Scope for methods that require numerical integration
|
||||||
* line is on the X axis, and solve the implicit equations for the X axis
|
* line is on the X axis, and solve the implicit equations for the X axis
|
||||||
* and the curve.
|
* and the curve.
|
||||||
*/
|
*/
|
||||||
function addCurveLineIntersections(v1, v2, curve1, curve2, locations, flip) {
|
function addCurveLineIntersections(v1, v2, curve1, curve2, locations) {
|
||||||
if (flip === undefined)
|
var flip = Curve.isLinear(v1),
|
||||||
flip = Curve.isLinear(v1);
|
vc = flip ? v2 : v1,
|
||||||
var vc = flip ? v2 : v1,
|
|
||||||
vl = flip ? v1 : v2,
|
vl = flip ? v1 : v2,
|
||||||
l1x = vl[0], l1y = vl[1],
|
l1x = vl[0], l1y = vl[1],
|
||||||
l2x = vl[6], l2y = vl[7],
|
l2x = vl[6], l2y = vl[7],
|
||||||
|
|
|
@ -36,8 +36,8 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
* @param {Number} parameter
|
* @param {Number} parameter
|
||||||
* @param {Point} point
|
* @param {Point} point
|
||||||
*/
|
*/
|
||||||
initialize: function CurveLocation(curve, parameter, point, _otherCurve,
|
initialize: function CurveLocation(curve, parameter, point, _curve2,
|
||||||
_otherParameter, _distance) {
|
_parameter2, _point2, _distance) {
|
||||||
// Define this CurveLocation's unique id.
|
// Define this CurveLocation's unique id.
|
||||||
this._id = CurveLocation._id = (CurveLocation._id || 0) + 1;
|
this._id = CurveLocation._id = (CurveLocation._id || 0) + 1;
|
||||||
this._curve = curve;
|
this._curve = curve;
|
||||||
|
@ -48,8 +48,9 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
this._segment2 = curve._segment2;
|
this._segment2 = curve._segment2;
|
||||||
this._parameter = parameter;
|
this._parameter = parameter;
|
||||||
this._point = point;
|
this._point = point;
|
||||||
this._otherCurve = _otherCurve;
|
this._curve2 = _curve2;
|
||||||
this._otherParameter = _otherParameter;
|
this._parameter2 = _parameter2;
|
||||||
|
this._point2 = _point2;
|
||||||
this._distance = _distance;
|
this._distance = _distance;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -110,17 +111,12 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
*/
|
*/
|
||||||
getIntersection: function() {
|
getIntersection: function() {
|
||||||
var intersection = this._intersection;
|
var intersection = this._intersection;
|
||||||
if (!intersection && this._otherCurve) {
|
if (!intersection && this._curve2) {
|
||||||
var param = this._otherParameter;
|
var param = this._parameter2;
|
||||||
// If we have the parameter on the other curve use that for
|
// If we have the parameter on the other curve use that for
|
||||||
// intersection rather than the point.
|
// intersection rather than the point.
|
||||||
this._intersection = intersection = new CurveLocation(
|
this._intersection = intersection = new CurveLocation(
|
||||||
this._otherCurve, param, param ? null : this._point, this);
|
this._curve2, param, this._point2 || this._point, this);
|
||||||
// Force calculate the other point from the parameter.
|
|
||||||
// DEBUG: @jlehni - Not sure why we have to do this? Shouldn't
|
|
||||||
// it auto-calculate upon first access?!
|
|
||||||
if (param)
|
|
||||||
intersection.getPoint();
|
|
||||||
intersection._intersection = this;
|
intersection._intersection = this;
|
||||||
}
|
}
|
||||||
return intersection;
|
return intersection;
|
||||||
|
@ -197,8 +193,8 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
||||||
* @type Point
|
* @type Point
|
||||||
* @bean
|
* @bean
|
||||||
*/
|
*/
|
||||||
getPoint: function() {
|
getPoint: function(/* uncached */) {
|
||||||
if (!this._point && this._parameter != null) {
|
if ((!this._point || arguments[0]) && this._parameter != null) {
|
||||||
var curve = this.getCurve();
|
var curve = this.getCurve();
|
||||||
this._point = curve && curve.getPointAt(this._parameter, true);
|
this._point = curve && curve.getPointAt(this._parameter, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ var Numerical = new function() {
|
||||||
return {
|
return {
|
||||||
TOLERANCE: 10e-6,
|
TOLERANCE: 10e-6,
|
||||||
// Precision when comparing against 0
|
// Precision when comparing against 0
|
||||||
// TODO: Find a good value
|
|
||||||
EPSILON: 10e-12,
|
EPSILON: 10e-12,
|
||||||
// Kappa, see: http://www.whizkidtech.redprince.net/bezier/circle/kappa/
|
// Kappa, see: http://www.whizkidtech.redprince.net/bezier/circle/kappa/
|
||||||
KAPPA: 4 * (sqrt(2) - 1) / 3,
|
KAPPA: 4 * (sqrt(2) - 1) / 3,
|
||||||
|
|
Loading…
Reference in a new issue