Permalink
Browse files

Merge pull request #227 from uxebu/fix-224-bbox-curve

Fixes #224 `getBoundingBox`
  • Loading branch information...
2 parents 7769d0d + f674e15 commit 464091f01866f7fc5051214533697c2abe2cd905 @davidaurelio davidaurelio committed Aug 28, 2014
@@ -0,0 +1,76 @@
+/**
+ * bounding box
+ */
+
+var paths = [
+ 'M352,5779.724c499,2-3-89,496-84',
+ 'M478,2877.472c247,3-255-88,244-83',
+ 'M478,2392.817c247,3-246,14,244-83',
+ 'M478,3361.031c247-69-246,14,244-83',
+ 'M500.5,1403.542c273-45-220,38,199-37',
+ 'M500.5,2587.469c215,96-220,38,199-37',
+ 'M406,1823.559c404,146-31,88,388,13',
+ 'M406,2064.553c86,150-31,88,388,13',
+ 'M406,4966.489c261,149-31,88,388,13',
+ 'M406,4484.496c382,141-31,88,388,13',
+ 'M394.5,6471.436c405,75-8,22,411-53',
+ 'M394.5,5279.895c449-4-8,22,411-53',
+ 'M394.5,6247.762c449-4,0,0,411-53',
+ 'M489.5,3565.342c449-4,0,0,221-8',
+ 'M479.072,3809.049c529-26,0,0,167-6',
+ 'M516.5,1644.744c352-80,0,0,167-6',
+ 'M798.002,4082.546c-529,7-523-141.999-12-38.999',
+ 'M801.469,6774.896c-550.999-16-522.999-142-1-140',
+ 'M799.765,4354.818c-542,32-523-142-1-140',
+ 'M770.439,7017.016c-380.001-148-523.001-142-1-140',
+ 'M769.988,274.009C390.988,266.009,247.988,272.009,769.988,274.009',
+ 'M794.813,1141.56C277.813,1150.56,272.813,1139.56,794.813,1141.56',
+ 'M785.217,901.998C320.216,900.998,263.217,899.998,785.217,901.998',
+ 'M347.5,462.172c505-17-17-18,505-16',
+ 'M339.5,663.235c521,0-1-1,521,1',
+ 'M377.5,5495.454c445,0-77-1,445,1',
+ 'M377.5,5978.951c372,1-77-1,445,1',
+ 'M564.756,3078.079c372,1-77-1-77-1',
+ 'M602.874,4750.803c196.999,91-77-1-77-1',
+ 'M731.169,7500.317c-551-16-74.463,21-1-140',
+ 'M731.169,7209.412c-551-4.777-74.463,6.271-1-41.811',
+ 'M1075.169,7682.533c-1996.043-2.379-269.747,3.121-3.622-20.811',
+ 'M612.657,8228.399c-57.988-464.354,2.249,314.834-1-140',
+ 'M748.791,9246.203c-48.561-445.45,0,0,0-246.418',
+ 'M407.051,9488.014c8.771-403.029,0,0,0-246.416',
+ 'M492,7954.201c258.471-128.029-126-68.002,216-56',
+ 'M529.006,8937.162c232.271-130.145,105.271-167.076,123.23-0.48',
+ 'M532.461,8453.83c213.563-131.8,105.271-167.076,123.232-0.479',
+ 'M538.385,8695.068c169.485-128.53,105.27-167.075,123.23-0.479',
+ 'M177.365,9657.754 C2314.484,9433.758-164.635,9645.75,177.365,9657.754',
+ 'M177.365,9863.064 C2314.484,9798.949-164.635,9859.629,177.365,9863.064',
+ 'M177.365,10098.412 C2314.482,10062.607-164.635,10096.492,177.365,10098.412',
+ 'M121.108,10352.402c2137.118-35.807,82,41-10.136-40.705',
+ 'M163.396,10885.141 C453.589,10902.539,162.471,10562.539,163.396,10885.141',
+ 'M228.071,10627.99 C1915.305,10622.137,202.129,10387.359,228.071,10627.99',
+ 'M152.222,10991.809 C1084.453,10959.602,1582.453,10868.578,152.222,10991.809',
+ 'M481.2,243.9 C 481.2,243.9,663.7,250.2,329,181.6 C329,181.6,198.7,118.5,198.7,118.5 C198.7,118.5,181,164.6,181,164.6 C181,164.6,185.3,162.5,185.3,162.5 C30.900000000000002,228.29999999999998,49.36666666666666,211.66666666666666,240.7,112.6 C240.7,112.6,555.8,68.5,519,103',
+ 'M185.3, 162.5 C 30.900000000000002,228.29999999999998,49.36666666666666,211.66666666666666,240.7,112.6'
+];
+
+for (var path, bounds, i = paths.length - 1; i >= 0; i--) {
+
+ path = new Path(paths[i]).attr({
+ fillColor: "#FFAAAA",
+ strokeColor: "black",
+ strokeWidth: 1
+ }).addTo(stage);
+
+ bounds = path.getBoundingBox();
+
+ new Rect(bounds.left, bounds.top, bounds.width, bounds.height).attr({
+ fillColor: "transparent",
+ strokeColor: "red",
+ strokeWidth: 1,
+ x: bounds.left,
+ y: bounds.top,
+ width: bounds.width,
+ height: bounds.height
+ }).addTo(stage);
+
+}
@@ -2,9 +2,6 @@
* bounding box
*/
-var box = new Arc(400, 400, 150, 1, 3, 1).addTo(stage).stroke('red',2).getBoundingBox();
-new Rect(box.left+400, box.top+400, box.width, box.height).stroke('green', 2).addTo(stage);
-
function Tracker(path) {
this.trackee = path;
this.group = new Group().addTo(path.parent);
@@ -24,7 +21,7 @@ Tracker.prototype = {
this.horz1.attr('y', box.top);
this.horz2.attr('y', box.bottom);
}
-}
+};
var star = Path.star(100, 100, 50, 5, 3);
@@ -51,3 +48,4 @@ function anim() {
}
);
}
+
@@ -144,7 +144,8 @@ movieList = {
'shape-fill-rule.js',
'shape-dashedstrokes.js',
'overlapping-paths.js',
- 'bounding-box.js'
+ 'bounding-box.js',
+ 'bounding-box-2.js'
],
'Test': [
'text.js',
@@ -138,7 +138,8 @@
"shape-center-of-arc.js",
"shape-fill-rule.js",
"overlapping-paths.js",
- "bounding-box.js"
+ "bounding-box.js",
+ "bounding-box-2.js"
],
"Test": [
"text.js",
@@ -597,7 +597,7 @@ define([
return curvedSegments;
};
- /**
+ /**
* Calculates the potential bounds of a single cubic bezier curve
* @param {Array} p0 The starting point of the curve in the form [x, y]
* @param {Array} curve A curveTo segment (e.g. `['curveTo',n,n,n,n,n,n]`)
@@ -615,28 +615,44 @@ define([
bounds[0].push(p3[0]);
bounds[1].push(p3[1]);
- for (var i = 0; i < 2; ++i) {
- var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
- var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
- var c = 3 * p1[i] - 3 * p0[i];
- if (a == 0) {
- if (b == 0) {
+ for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
+
+ b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+ a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+ c = 3 * p1[i] - 3 * p0[i];
+
+ // Cast to int. This fixes floating point arithmetic issues as reported
+ // here: https://github.com/uxebu/bonsai/issues/224
+ b = b | 0;
+ a = a | 0;
+ c = c | 0;
+
+ if (a === 0) {
+
+ if (b === 0) {
continue;
}
- var t = -c / b;
+
+ t = -c / b;
+
if (0 < t && t < 1) {
bounds[i].push(f(t));
}
continue;
}
- var b2ac = pow(b, 2) - 4 * c * a;
+
+ b2ac = pow(b, 2) - 4 * c * a;
+
if (b2ac < 0) {
continue;
}
- var t1 = (-b + sqrt(b2ac))/(2 * a);
+
+ t1 = (-b + sqrt(b2ac))/(2 * a);
if (0 < t1 && t1 < 1) bounds[i].push(f(t1));
- var t2 = (-b - sqrt(b2ac))/(2 * a);
+
+ t2 = (-b - sqrt(b2ac))/(2 * a);
if (0 < t2 && t2 < 1) bounds[i].push(f(t2));
+
}
// Return bounds in the form `[ xBoundsArray, yBoundsArray ]`
@@ -648,8 +664,8 @@ define([
};
function f(t) {
- return pow(1-t, 3) * p0[i]
- + 3 * pow(1-t, 2) * t * p1[i]
+ return pow(1-t, 3) * p0[i]
+ + 3 * pow(1-t, 2) * t * p1[i]
+ 3 * (1-t) * pow(t, 2) * p2[i]
+ pow(t, 3) * p3[i];
}
@@ -734,7 +734,7 @@ define([
* @param {Number} radius The radius of the ellipse
* @param {deg|rad} aStartAngle Starting angle of arc in radians
* @param {deg|rad} aEndAngle Ending angle of arc in radians
- * @param {Boolean} [anticlockwise] Whether you want the arc to be drawn
+ * @param {Boolean} [anticlockwise] Whether you want the arc to be drawn
* anticlockwise or clockwise (Boolean)
* @returns {Path} The current Path instance
*/
@@ -761,16 +761,6 @@ define([
};
/**
- * Returns the bounding box of that {Path}.
- *
- * @returns {Object} bb An object with x, y, width, height
- * @ignore
- */
- proto.boundingBox = function() {
- throw 'Not implemented';
- };
-
- /**
* Returns a point at a certain length
*
* @see pathLength
@@ -1167,7 +1157,7 @@ define([
box.height = box.bottom - box.top;
return box;
-
+
};
return Path;
@@ -947,6 +947,22 @@ define([
bottom: 342.8039531991939
});
});
+ it('Returns bounds of cubic bezier where control-points trigger "floating point overflow" issues', function() {
+ expect(
+ CurvedPath.getBoundsOfCurve(
+ 185.3, 162.5,
+ 30.900000000000002, 228.29999999999998,
+ 49.36666666666666, 211.66666666666666,
+ 240.7, 112.6
+ )
+ ).toEqual({
+ // Verified visually
+ top: 112.6,
+ left: 81.87046483579125,
+ right: 240.7,
+ bottom: 201.89216959792813
+ });
+ });
});
});

0 comments on commit 464091f

Please sign in to comment.