mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -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,
|
||||
success: success
|
||||
});
|
||||
console.log(found);
|
||||
console.log(ixsPaper.length, found);
|
||||
if (!success) {
|
||||
var ser = new XMLSerializer();
|
||||
console.log('failcase:', ser.serializeToString(path1.exportSVG()),
|
||||
|
|
|
@ -19,6 +19,6 @@ var options = {
|
|||
browser: true,
|
||||
stats: true,
|
||||
svg: true,
|
||||
fatline: false,
|
||||
fatline: true,
|
||||
debug: false
|
||||
};
|
||||
|
|
|
@ -869,7 +869,7 @@ statics: {
|
|||
step /= 2;
|
||||
}
|
||||
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));
|
||||
},
|
||||
|
||||
|
@ -966,7 +966,7 @@ new function() { // Scope for methods that require numerical integration
|
|||
a = 0;
|
||||
if (b === undefined)
|
||||
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]) {
|
||||
// Straight line
|
||||
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
|
||||
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)
|
||||
var first = locations[0],
|
||||
last = locations[locations.length - 1];
|
||||
if ((!first || !point.equals(first._point))
|
||||
&& (!last || !point.equals(last._point)))
|
||||
locations.push(new CurveLocation(curve1, t1, point, curve2, t2));
|
||||
if ((!first || !point1.equals(first._point))
|
||||
&& (!last || !point1.equals(last._point)))
|
||||
locations.push(
|
||||
new CurveLocation(curve1, t1, point1, curve2, t2, point2));
|
||||
}
|
||||
|
||||
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
|
||||
// numerically unstable when one of the curves has converged to a point
|
||||
// and the other hasn't.
|
||||
while (iteration++ < 20
|
||||
&& (Math.abs(range1[1] - range1[0]) > /*#=*/ Numerical.TOLERANCE
|
||||
|| Math.abs(range2[1] - range2[0]) > /*#=*/ Numerical.TOLERANCE)) {
|
||||
while (iteration++ < 20) {
|
||||
// First we clip v2 with v1's fat-line
|
||||
var range,
|
||||
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
|
||||
// method if both of the parameter ranges have converged reasonably well
|
||||
// (according to Numerical.TOLERANCE).
|
||||
if (Math.abs(range1[1] - range1[0]) < /*#=*/ Numerical.TOLERANCE &&
|
||||
Math.abs(range2[1] - range2[0]) < /*#=*/ Numerical.TOLERANCE) {
|
||||
// method if both of the parameter ranges have converged reasonably
|
||||
// well (according to Numerical.TOLERANCE).
|
||||
if (Math.abs(range1[1] - range1[0]) <= /*#=*/ Numerical.TOLERANCE &&
|
||||
Math.abs(range2[1] - range2[0]) <= /*#=*/ Numerical.TOLERANCE) {
|
||||
var t1 = (range1[0] + range1[1]) / 2,
|
||||
t2 = (range2[0] + range2[1]) / 2;
|
||||
addLocation(locations, curve1, t1,
|
||||
Curve.evaluate(v1, t1, true, 0), curve2, t2);
|
||||
addLocation(locations,
|
||||
curve1, t1, Curve.evaluate(v1, t1, true, 0),
|
||||
curve2, t2, Curve.evaluate(v2, t2, true, 0));
|
||||
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
|
||||
* and the curve.
|
||||
*/
|
||||
function addCurveLineIntersections(v1, v2, curve1, curve2, locations, flip) {
|
||||
if (flip === undefined)
|
||||
flip = Curve.isLinear(v1);
|
||||
var vc = flip ? v2 : v1,
|
||||
function addCurveLineIntersections(v1, v2, curve1, curve2, locations) {
|
||||
var flip = Curve.isLinear(v1),
|
||||
vc = flip ? v2 : v1,
|
||||
vl = flip ? v1 : v2,
|
||||
l1x = vl[0], l1y = vl[1],
|
||||
l2x = vl[6], l2y = vl[7],
|
||||
|
|
|
@ -36,8 +36,8 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
* @param {Number} parameter
|
||||
* @param {Point} point
|
||||
*/
|
||||
initialize: function CurveLocation(curve, parameter, point, _otherCurve,
|
||||
_otherParameter, _distance) {
|
||||
initialize: function CurveLocation(curve, parameter, point, _curve2,
|
||||
_parameter2, _point2, _distance) {
|
||||
// Define this CurveLocation's unique id.
|
||||
this._id = CurveLocation._id = (CurveLocation._id || 0) + 1;
|
||||
this._curve = curve;
|
||||
|
@ -48,8 +48,9 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
this._segment2 = curve._segment2;
|
||||
this._parameter = parameter;
|
||||
this._point = point;
|
||||
this._otherCurve = _otherCurve;
|
||||
this._otherParameter = _otherParameter;
|
||||
this._curve2 = _curve2;
|
||||
this._parameter2 = _parameter2;
|
||||
this._point2 = _point2;
|
||||
this._distance = _distance;
|
||||
},
|
||||
|
||||
|
@ -110,17 +111,12 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
*/
|
||||
getIntersection: function() {
|
||||
var intersection = this._intersection;
|
||||
if (!intersection && this._otherCurve) {
|
||||
var param = this._otherParameter;
|
||||
if (!intersection && this._curve2) {
|
||||
var param = this._parameter2;
|
||||
// If we have the parameter on the other curve use that for
|
||||
// intersection rather than the point.
|
||||
this._intersection = intersection = new CurveLocation(
|
||||
this._otherCurve, param, param ? null : 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();
|
||||
this._curve2, param, this._point2 || this._point, this);
|
||||
intersection._intersection = this;
|
||||
}
|
||||
return intersection;
|
||||
|
@ -197,8 +193,8 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
|
|||
* @type Point
|
||||
* @bean
|
||||
*/
|
||||
getPoint: function() {
|
||||
if (!this._point && this._parameter != null) {
|
||||
getPoint: function(/* uncached */) {
|
||||
if ((!this._point || arguments[0]) && this._parameter != null) {
|
||||
var curve = this.getCurve();
|
||||
this._point = curve && curve.getPointAt(this._parameter, true);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ var Numerical = new function() {
|
|||
return {
|
||||
TOLERANCE: 10e-6,
|
||||
// Precision when comparing against 0
|
||||
// TODO: Find a good value
|
||||
EPSILON: 10e-12,
|
||||
// Kappa, see: http://www.whizkidtech.redprince.net/bezier/circle/kappa/
|
||||
KAPPA: 4 * (sqrt(2) - 1) / 3,
|
||||
|
|
Loading…
Reference in a new issue