Bezier Curve (Bezier Curve) is widely used in the field of computer graphics, such as CSS animation, Canvas and Photoshop.

The article directories

  • I. What is a Bessel curve?
  • What are the types of Bessel curves?
  • 3. How is the Bezier curve drawn?
  • How to find the coordinates of points on the Bessel curve?
    • 1. First order Bessel curve
    • 2. Second order Bessel curve
    • Third order Bessel curve
    • 4. Bessel curves of multiple orders
  • How to implement a third-order Bezier curve constructor similar to the Easing property in CSS?
  • How to use higher order Bessel curve to express lower order Bessel curve?

I. What is a Bessel curve?

The Bezier curve was widely published in 1962 by Pierre Bezier, a French engineer who used it to design the main body of a car.

Bezier curves are mainly used for mathematical curves in two-dimensional graphics applications. Curves are composed of starting points, ending points (also called anchor points) and control points. By adjusting the control points, the shape of bezier curves drawn in certain ways will change. The drawing method is described in detail later.

In computer graphics is a widely use beisaier curve, such as Photoshop effect of pen, Flash5 bezier tool, generally in the software GUI development will provide the corresponding ways to implement beisaier curve, transition time function is also known as CSS animation by Bessel curve (third order Bessel curve).

What are the types of Bessel curves?

According to the number of control points, Bessel curve can be divided into:

  • First order Bessel curve (2 control points)
  • Second order Bessel curve (3 control points)
  • Third order Bessel curve (4 control points)
  • Bessel curve of order n (Control points)

3. How is the Bezier curve drawn?

The figure below is a third-order Bezier curve, including four control points, respectively.

So how do we draw a Bezier curve with control points?

Based on the example of the third-order Bessel curve in the figure above, the basic steps are as follows:

  1. The four control points are connected in sequence to form three line segments, as shown in the figure aboveAnd then pass a parameterThe value of this parameter is equal to the length of a point on the segment from the starting point divided by the length of the segment. likeI have a point on this line segmentAt this time,The value is, includingThe location is shown in the following figure.

  1. We then do the same for each line segment to get three control points, as shown in the figure below.

  1. Then repeat the first step to these three control points to get two control points, as shown in the figure below.

  1. And then you can do the same thing at the end, and you get to the final pointAs shown in the figure below, this point is a point on the Bessel curve.

By controlling theThe value of, from 0 to 1, draws a line from the starting pointTo the endBessel curve of theta.

You can get a sense of the drawing process with this animation:

How to find the coordinates of points on the Bessel curve?

1. First order Bessel curve

For first order Bessel curves, we can use geometry, and it’s very easy to useIs worth the coordinates of the point on the outbound segment:

Then we can get:

2. Second order Bessel curve

For a second order Bessel curve, you can actually think of it as: inUse the first order formula to find the pointAnd then inUse the first order formula to find the pointAnd finally theAnd then we can use the first order formula to figure out the points on the final Bessel curve. The specific derivation process is as follows:

Let’s figure out the control points on the line segment.

Insert the above formula into the following formula:

The following formula is obtained:

Third order Bessel curve

Similar to the second-order Bessel curve, the following coordinate formula can be obtained by the same method:

4. Bessel curves of multiple orders

I’m just going to do it right hereOrder Bessel curve formula is given, interested students can study on their own.

That is:

In the formulaThe value ofIs related to statistics. Those who are interested can have a look at mineThis article.

Among themThe value is:

How to implement a third-order Bezier curve constructor similar to the Easing property in CSS?

If we want to implement a third-order Bessel curve like this, we need to not only get some points on the curve, but we also need to get the y-coordinates from the X-axis.

The easing Bezier curve in CSS has a characteristic that the starting point and the ending point are fixed, i.e. So there are only two unknown points, which means you have to pass in four values, and those four values have to be in the range ofInside.

So we need to create a CubicBezier class that has controlPoints:

class CubicBezier {
  constructor(x1, y1, x2, y2) {
    this.controlPoints = [x1, y1, x2, y2]; }}Copy the code

After initializing with the above code, we also need to determine the value of t (in the range of) value to get the coordinates, and an array of coordinate sets on the curve. In addition, you need to use the third-order Bessel formula:

becauseThe point coordinates are [0, 0],Point coordinates ofThus, the formula can be written as:

class CubicBezier {
  constructor(x1, y1, x2, y2) {
    this.controlPoints = [x1, y1, x2, y2];
  }

  getCoord(t) {
    // If t is not between 0 and 1, the operation is terminated
    if (t > 1 || t < 0) return;
    const _t = 1 - t;
    const [ x1, y1, x2, y2 ] = this.controlPoints;
    const coefficient1 = 3 * t * Math.pow(_t, 2);
    const coefficient2 = 3 * _t * Math.pow(t, 2);
    const coefficient3 = Math.pow(t, 3);
    const px = coefficient1 * x1 + coefficient2 * x2 + coefficient3;
    const py = coefficient1 * y1 + coefficient2 * y2 + coefficient3;
    // Only three significant digits are retained in the result
    return [parseFloat(px.toFixed(3)), parseFloat(py.toFixed(3))]; }}Copy the code

Using the above Bezier class, we can build Bezier instance according to the two control points, through this instance we can according to the T value, get the approximate value on the point.

So if we want to get the Y-axis from the X-axis, what do we do?

Here I use an approximate treatment method, which is as follows:

  1. First get the two points closest to the desired value.
  2. And then you go through these two points and you get the equation of the line.
  3. Finally, by passing the x-coordinate into the equation of the line, we can approximate the y-coordinate.

Therefore, we need to further modify the Bezier constructor. We need to cache the attribute coords of a fixed number of coordinate arrays, and the method getCoordsArray to get coords. Finally, we need to get the method getY to get the Y-axis coordinates.

class CubicBezier {
  constructor(x1, y1, x2, y2) {
    const precision = 100;
    this.controlPoints = [x1, y1, x2, y2];
    this.coords = this.getCoordsArray(precision);
  }
  
  getCoord(t) {
    // If t is not between 0 and 1, the operation is terminated
    if (t > 1 || t < 0) return;
    const _t = 1 - t;
    const [ x1, y1, x2, y2 ] = this.controlPoints;
    const coefficient1 = 3 * t * Math.pow(_t, 2);
    const coefficient2 = 3 * _t * Math.pow(t, 2);
    const coefficient3 = Math.pow(t, 3);
    const px = coefficient1 * x1 + coefficient2 * x2 + coefficient3;
    const py = coefficient1 * y1 + coefficient2 * y2 + coefficient3;
    // Only three significant digits are retained in the result
    return [parseFloat(px.toFixed(3)), parseFloat(py.toFixed(3))];
  }
  
  getCoordsArray(precision) {
    const step = 1 / (precision + 1);
    const result = [];
    for (let t = 0; t <= precision + 1; t++) {
      result.push(this.getCoord(t * step));
    }
    this.coords = result;
    return result;
  }
  
  getY(x) {
    if (x >= 1) return 1;
    if (x <= 0) return 0;
    let startX = 0;
    for (let i = 0; i < this.coords.length; i++) {
      if (this.coords[i][0] >= x) {
        startX = i;
        break; }}const axis1 = this.coords[startX];
    const axis2 = this.coords[startX - 1];
    const k = (axis2[1] - axis1[1]) / (axis2[0] - axis1[0]);
    const b = axis1[1] - k * axis1[0];
    // The result will retain only three significant digits
    return parseFloat((k * x + b).toFixed(3)); }}Copy the code

Then you can use our CubicBezier in the following ways:

const cubicBezier = new CubicBezier(0.3.0.1.0.3.1);
cubicBezier.getY(0.1); / / 0.072
cubicBezier.getY(0.7); / / 0.931
Copy the code

I have written an inanimate Scroll library for this CubicBezier constructor. Please check out the source code.

How to use higher order Bessel curve to express lower order Bessel curve?

aOrder Bessel curves can be passed through a shape completely consistentOrder Bessel curve. So what do we have to do to get thisWhat about Bessel curves of order?

The process by which a higher order Bessel curve represents a lower order Bessel curve is called ascending.

We need to useLet’s do the ascending order of this equation.

  1. Take the second order up to the third order as an example, the coordinate formula of the second order Bessel curve is:

Insert the following equation into the above formula:

Then the following formula is obtained:

According to the above results, the control point can be obtained from the previousTurned out to be..andFour control points, thus completing the upgrade.

  1. So if we take any value of n, how do we go up? (The following is the derivation process, if you are not interested, you can directly jump to the formula below 👇)

There is some derivation here (the derivation here needs to be usedFormula, interested students can derive their own), because:

Bessel’s formula can be expressed as:

By substituting the above two equations, we get:

Because whenWhen:

Therefore, the formula can be written as:

And because:

whenWhen:

So:

By substituting the above two equations (1) and (2) into formula (0), the following ascending formula can be obtained:

That’s about it for the basics of the Bessel curve, so if you find any inaccuracies or additions, feel free to point them out in the comments 😊.

reference

  • Bezier Curve – Wikipedia, the free encyclopedia
  • Bezier curve – The Modern Javascript Tutorial