Comments (3)
This should do the trick (Tests: http://jsbin.com/ivomiq/56/, http://jsbin.com/hotakayi/1/ ):
// Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
// Original version: NISHIO Hirokazu
// Modifications: Timo
function getBoundsOfCurve (x0, y0, x1, y1, x2, y2, x3, y3)
{
var tvalues = [], bounds = [new Array(6), new Array(6)],
a,b,c,t,t1,t2,b2ac,sqrtb2ac;
for (var i = 0; i < 2; ++i)
{
if (i==0)
{
b = 6 * x0 - 12 * x1 + 6 * x2;
a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
c = 3 * x1 - 3 * x0;
}
else
{
b = 6 * y0 - 12 * y1 + 6 * y2;
a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
c = 3 * y1 - 3 * y0;
}
if (abs(a) < 1e-12)
{
if (abs(b) < 1e-12) continue;
t = -c / b;
if (0 < t && t < 1) tvalues.push(t);
continue;
}
b2ac = b*b - 4 * c * a;
sqrtb2ac = sqrt(b2ac);
if (b2ac < 0) continue;
t1 = (-b + sqrtb2ac) / (2 * a);
if (0 < t1 && t1 < 1) tvalues.push(t1);
t2 = (-b - sqrtb2ac) / (2 * a);
if (0 < t2 && t2 < 1) tvalues.push(t2);
}
var j = tvalues.length, jlen = j, mt;
while(j--)
{
t = tvalues[j];
mt = 1-t;
bounds[0][j] = (mt*mt*mt*x0) + (3*mt*mt*t*x1) + (3*mt*t*t*x2) + (t*t*t*x3);
bounds[1][j] = (mt*mt*mt*y0) + (3*mt*mt*t*y1) + (3*mt*t*t*y2) + (t*t*t*y3);
}
//tvalues[jlen] = 0;
//tvalues[jlen+1] = 1;
bounds[0][jlen] = x0;
bounds[1][jlen] = y0;
bounds[0][jlen+1] = x3;
bounds[1][jlen+1] = y3;
bounds[0].length = bounds[1].length = jlen+2;
return {
left: min.apply(null, bounds[0]),
top: min.apply(null, bounds[1]),
right: max.apply(null, bounds[0]),
bottom: max.apply(null, bounds[1])
};
};
EDIT: Removed unnecessary x,y and commented tvalues[jlen] = 0;
and tvalues[jlen+1] = 1;
. I used x, y to get the real bound coordinates, but when only bounding box is needed, they are unnecessary. I have used this function to get local extremes (to split cubic on them for use in cubic flattening to lines) in which case it was needed to return only tvalues
array.
from bonsai.
Thanks @timo22345! Will investigate soon.
from bonsai.
Hi @timo22345, thanks for taking the time to report this issue. I investigated a little bit further and found out that casting the intermediate results "a", "b" and "c" to int also fixes the issue. I added visual and unit tests. Do you see any problems with my fix?
I searched for the string "http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html" on Github an found several other implementations. Other implementations store the intermediate result as doubles or int. That got me to deal with that approach, too.
from bonsai.
Related Issues (20)
- clone() without attributes not working
- How I can use CSS styling for SVG files I load with BonsaiJS? HOT 1
- textAlign property not working HOT 4
- Save SVG to Image on tick HOT 7
- npm does not install HOT 1
- Chrome trips over SVG attribute spreadMethod with an uppercase value "PAD"
- Rookie Question: How to use variable in the attr? HOT 2
- GitHub pages site doesn't work HOT 2
- Documentation seems to be down HOT 2
- Layering Tests No. 2 and 3 fail HOT 1
- Morphing Demo fails
- Is there a way to make it responsive? HOT 1
- Revive this project! HOT 6
- Node.js? HOT 3
- Renders wrong after `clone()`, with a `rotation` attr
- The (phantom) tests are hard to run HOT 1
- Website demos are not working HOT 9
- code is not align
- all demos fail HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bonsai.