First, what is a Bezier curve
In 1962, the French engineer Pierre Bessel (Pierre Bézier), the Bezier curve, invented the Bezier curve to solve the design problem of the main body of the car. Today, the Bezier curve is a very important curve in computer graphics, which can elegantly simulate the lines drawn by hand. It creates and edits graphics by controlling the points on the curve (starting point, ending point, and multiple reference points). One of the important functions is the control line located in the center of the curve. This line is virtual, and the middle is crossed with a Bezier curve, and the ends are control endpoints. The Bezier curve changes the curvature of the curve (the degree of curvature) when moving the ends of the endpoints, and when moving the middle point (that is, moving the virtual control line), the Bezier curve moves evenly when the start and end points are locked.
Application of Bezier Curve
Bezier curves are widely used in drawing software, such as Adobe PhotoShop, Adobe Flash.
Android can implement Bezier curves with custom view
iOS can use the Uibezierpath class to generate Bezier curves
Front end, canvas beziercurveto,css animation-timing-function:cubic-bezier (x,x,x,x} have some applications for Bezier curves
Three, Bezier curve formula and its analysis
A:
Two times:
Three times:
N Times
But the formula only gives the relationship between point and point, and does not give the relationship between Y and X coordinate, for this we need to decompose it, the following three times Bezier curve as an example:
The application of Bezier curve in animation
, the X-axis represents the time, and the y-axis is used to indicate the completion of the animation. So the application of Bezier curve in the animation is very simple, every time the execution time of the current animation in the proportion of the total time and then you can get the animation at this time to complete the degree, and finally only need to set the time of this moment the completion of the animation on the line. Since its starting coordinates are (0,0), respectively (in).
JS Code Implementation
We have already found the relationship between x, Y and T of three Bezier curves, so we can use JS to implement this relationship.
functionUnitbezier(P1X,P1Y,P2X,P2Y) {This.cx =3.0 * P1X;THIS.BX =3.0 * (P2X-P1X)-this.cx;THIS.AX =1.0-THIS.CX-THIS.BX;This.cy =3.0 * P1Y;this.by = 3.0 * (p2y-p1y)-this.cy; this.ay = 1.0-this.cy-this.by;} Unitbezier.prototype = {samplecurvex: function (t) {return ((this.ax * t + THIS.BX) * t + this.cx) * t; }, Samplecurvey: function (t) { Span class= "Hljs-keyword" >return ((this.ay * t + this.by) * t + Span class= "Hljs-keyword" >this.cy) * t; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
Perhaps to feel here, we have implemented the Bezier curve in the animation of the application, we look at this demo.
However, we find that the original JS implementation animation effect is significantly different from the animation effect in CSS3. So how do you simulate it? Look at the following code:
functionUnitbezier(P1X,P1Y,P2X,P2Y) {This.cx =3.0 * P1X;THIS.BX =3.0 * (P2X-P1X)-this.cx;THIS.AX =1.0-THIS.CX-THIS.BX;This.cy =3.0 * P1Y;This.by =3.0 * (P2Y-P1Y)-this.cy;This.ay =1.0-This.cy-this.by;} Unitbezier.prototype = {Samplecurvex:function (t) {//Bézier curve T moment coordinates x coordinate point return ((this.ax * t + this.bx) * t + this.cx) * t; }, Samplecurvey: function (t) { Span class= "hljs-comment" >//the coordinate point of the Bezier T moment in the y-coordinate of the return ((this.by) * t + this.cy) * t; }, Solve:function (t) {this.samplecurvey (this.samplecurvex (t))}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
Let's test it again and look at the effect.
Well, that's a bigger difference. But think about all the data here is basically floating point arithmetic, then the error can be imagined.
Five, floating-point operation error
The error caused by floating-point operations in a computer is very common, whether C, C + +, Java, JavaScript wait languages exist, because they are based on the IEEE 754 standard for floating-point operations.
IEEE 754
In accordance with the IEEE 754 standard, 32 bits are:
- 1-bit is sign bit
- 8 bits is the digit (exponent)
- 23 bits is numeric (fraction)
Then the calculated result is:
Give me some chestnuts.
For example, 0.1 of single-precision floating-point numbers in the computer binary number is:
0 01111011 10011001100110011001101
Then the actual value is
For example, 0.5 of single-precision floating-point numbers in the computer binary number is:
0 01111110 00000000000000000000000
Vi. How to reduce the error caused by floating-point operation
First, we can look at the simplest way to reduce the error.
Amplification method
Because the floating-point operation generates an error, we can magnify it in a disguised way, knowing that it is an integer and returning the value at the end of the time, which is to completely eliminate the error.
Math.formatFloat = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f*m,10) m;
}
var NumA = 0.1;
var NumB = 0.2;
Alert (Math.formatfloat (numa+numb,1) ===0.3);
Although this method can eliminate errors well in JS, not all scenarios are adapted. It is relatively simple to add and subtract operations and a lower number of multiplication division operations, this is because the range of exact integers in JS is defined as:? 9007199254740992 to 9007199254740992 (2 of 53), which means up to 16 bits. However, our Bezier application will certainly produce floating-point numbers that exceed 16 bits in the animation process, which still does not solve the problem.
Two-part method
Dichotomy is when we were in high school, the teacher has told us, but at that time is usually used to determine whether F (x0) is positive or negative, and sometimes give precision requirements. Here we can also use dichotomy to solve, we only need to constantly use the dichotomy method to find (f (x0)-X)
function division (X,T1,T2, epsilon,func) {//calculates the approximate value of x var t0, T1, T2, x2, i; t2 = x; if (T2 < t0) return t0; if (T2 > T1) return T1; while (T0 < t1) {x2 = func (t2); if (math.abs (x2-x) < epsilon) return T2; if (x > x2) t0 = t2; else t1 = t2; t2 = (t1-t0) * .5 + t0;} return T2; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21st
- 22
Newton Iterative Method
Newton's Iterative method is also often used to reduce the error in the computer, a common method, the formula is as follows:
Set R is the root of f (x) =0, select x0 as the initial approximation of R, over Point (x0,f (x0)) to do curve tangent l,l equation for y=f (x0) +f ' (x0) (x-x0), to find the L and X-axis intersection of the horizontal x1=x0-f (x0)/F ' (x0), The X1 is called an approximate value of R. Point the tangent of the curve and find the horizontal axis of the intersection of the tangent and the x-axis, called the two approximate value of R. Repeat the above process to get an approximate sequence of R, where Xn+1=xn-f (xn)/f ' (xn) is called the N+1 secondary approximation of R.
In the process of processing Bezier curves, since we are not able to find truly accurate values, we only need to meet the F (x0)-X
The final effect
Finally, very close to the CSS3 of the Bezier curve animation effect, although there is still a little difference, this is because the method can only make the error can only be reduced and not be eliminated, and the more accurate, then JS animation performance is worse, so here the accuracy is set to 0.01.
See here in the original (http://www.yuchenblog.cn/?p=102)
JS Analog CSS3 Animation-Bezier curve