[30 minutes to finish] canvas animation game Basics (3): speed and acceleration

Time:2020-8-10

preface

The last article has basically laid a good foundation for canvas. This article mainly introduces the classical physical concepts of speed and acceleration, and discusses their application in programming animation.
Before reading, please understand the basic knowledge of speed and acceleration, as well as vector and vector addition.
My ability is limited, welcome to discuss together, criticize and correct.

speed

Speed is a physical quantity that describes the speed and direction of an object. In physics, the velocity of an object usually refers to its instantaneous velocity. The unit of speed in the international system of units is meter per second, the international symbol is m / s, and the Chinese symbol is meter / second. In the framework of relativity, the upper limit of the speed of an object is the speed of light.

In animation programming, speed is the most basic element, which is reflected in the second part of this series.

Speed in animation programming

As shown in the figure below, the speed in computer animation we are going to discuss here is similar to the concept in physics, which is vectorIt has both size and directionThe direction is reflected by the positive and negative values. In the coordinate system mentioned in Chapter 1 of the review series, the velocity along the positive half axis is positive, and the velocity along the negative half axis is negative.
Another difference is the unit, which may not be in timeIn framesSuch as “pixel / frame”.
Because speed is a vector, any speed can be decomposed into the speed on x-axis and y-axis, which is the basic idea of programming animation.

[30 minutes to finish] canvas animation game Basics (3): speed and acceleration

Case application

In the second part of the series, “an arrow that can track the position of the mouse” is transformed into “an arrow following the mouse”. The code is very basic, just look at the comments

  1. Calculate the angle between the target point and the object;
  2. The velocity and the angle between X and Y axis are decomposed according to;
  3. The velocity on each axis is added to the position coordinates of the object.

In particular, because the animation loop in this example is frame based, the unit of speed isPixels per frame
Complete example: follow the arrow of the mouse

/**
 *Follow the arrow of the mouse
 * */
window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const mouse = utils.captureMouse(canvas);
  const arrow = new Arrow();
  //Set speed
  const speed = 3;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    //Calculate the relative distance between the mouse and the arrow
    const dx = mouse.x - arrow.x;
    const dy = mouse.y - arrow.y;
    //Find the angle of the arrow pointing to the mouse
    const angle = Math.atan2(dy, dx);
    //Decompose the velocity into x-axis and y-axis
    const vx = Math.cos(angle) * speed;
    const vy = Math.sin(angle) * speed;
    //Sets the angle of the arrow
    arrow.rotation = angle;
    //Add the decomposed speed to the two axes of the arrow
    arrow.x += vx;
    arrow.y += vy;
    //Redraw arrow
    arrow.draw(context);
  }());
};

acceleration

[science popularization] acceleration is a physical quantity and a vector in physics. It is mainly used in classical physics. It is generally represented by the letter A. in the international system of units, the unit is meter per second. Acceleration is the rate of change of velocity vector to time, which describes the speed and direction of velocity change.

Acceleration in animation programming

The acceleration in computer animation isVariation of speedLike the previous velocity, it is a vector, which can also be decomposed into accelerations on the x-axis and y-axis in the same way. The unit can be a pixel per square frame, which has a lot to do with “Mechanics”.
Acceleration can make motion more natural, so it is necessary to simulate real motion in computer animation.
Please make sure that acceleration is the change of velocity, that is, the direction of acceleration is the same as that of speed, that is, acceleration, and the opposite direction is deceleration. If the acceleration is zero, the speed will be constant and the object will move in a uniform straight line.

Case application

Continue to modify the previous example to follow the arrow of the mouse to “the arrow accelerating towards the mouse direction”. The amount of transformation is not large, that is, the acceleration is decomposed and added to the velocity

  1. Calculate the angle between the target point and the object;
  2. The acceleration is also decomposed into x and Y axes;
  3. The acceleration and velocity on each axis are added respectively;
  4. Then the velocity on each axis is added to the position coordinates of the object.

Full example: arrow to accelerate in mouse direction
If you observe the example, you will find that although the arrow moves more naturally than the previous example, it will never stop. This is because the acceleration here is constant, but in reality, the acceleration will be reduced due to friction and other factors.

/**
 *Arrow to accelerate in mouse direction
 * */
window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const mouse = utils.captureMouse(canvas);
  const arrow = new Arrow();
  //Initialization speed
  let vx = 0;
  let vy = 0;
  //Set acceleration
  const force = 0.02;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    //Calculate the relative distance between the mouse and the arrow
    const dx = mouse.x - arrow.x;
    const dy = mouse.y - arrow.y;
    //Find the angle of the arrow pointing to the mouse
    const angle = Math.atan2(dy, dx);
    //The acceleration is decomposed into x-axis and y-axis
    const ax = Math.cos(angle) * force;
    const ay = Math.sin(angle) * force;
    //Sets the angle of the arrow
    arrow.rotation = angle;
    //Add the decomposed acceleration to the two axis velocities of the arrow
    vx += ax;
    vy += ay;
    //Add the decomposed speed to the two axes of the arrow
    arrow.x += vx;
    arrow.y += vy;
    //Redraw arrow
    arrow.draw(context);
  }());
};

Proportional motion

Here are two more advanced common techniques, jogging and bouncing.
The so-called proportional motion means that the degree of motion is directly proportional to the distance of the target point. In short, “the farther the distance is, the greater the degree of motion” isRefers to but not limited to velocity and accelerationMotion related variables.

Slow motion

Slow motion meansThe speed of an object is proportional to its distance from the target pointThat is, the proportional speed based on distance, which will affect the speed.
There are more than one movement characteristics of slow motion. You can first slow down, slow down first, slow later fast, and so on. Here we only take the simplest fast first slow as an exampleThe greater the distance, the greater the speed. If the distance is indented to 0, the speed is also 0

The code is as follows: the basic idea is as follows:

  1. Determine a scale coefficient, which is a decimal between 0 and 1;
  2. Determine the target point and calculate the relative distance;
  3. Calculate the speed, speed = distance × scale coefficient;
  4. Add the current position to the current position;
  5. Repeat steps 2-4 until the object reaches the target point.

To the full position of the mouse: arrow

/**
 *Arrow moving slowly towards the mouse
 * */
window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const mouse = utils.captureMouse(canvas);
  const arrow = new Arrow();
  //Scale factor
  const easing = 0.05;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    //Calculate the relative distance between the mouse and the arrow
    const dx = mouse.x - arrow.x;
    const dy = mouse.y - arrow.y;
    //Find the angle of the arrow pointing to the mouse
    const angle = Math.atan2(dy, dx);
    //Inching according to distance
    const vx = dx * easing;
    const vy = dy * easing;
    //Sets the angle of the arrow
    arrow.rotation = angle;
    //Add the decomposed speed to the two axes of the arrow
    arrow.x += vx;
    arrow.y += vy;
    //Redraw arrow
    arrow.draw(context);
  }());
};

Bounce

Moving finger is a bulletThe acceleration of an object is proportional to its distance from the target pointThat is, the proportional acceleration based on distance, which will affect the magnitude of acceleration.
Bouncing makes the movement natural and spiritual. You will find that the object will rush through the target point, and then it will rebound and go back and forth. So you can simulate the effect of a spring or rubber band.
In particular, when the distance is 0, the acceleration is also 0, but the velocity is not necessarily 0.

The code is as follows: This is very similar to the previous acceleration example, which is constantly reciprocating. The reason is that the acceleration and speed are difficult to be 0 at the same time. Here we add a reduction coefficient to make it stop

  1. Determine a scale coefficient, which is a decimal between 0 and 1;
  2. Determine the target point and calculate the relative distance;
  3. Calculate velocity, acceleration = distance × scale coefficient;
  4. Use the current speed plus acceleration;
  5. Add the current position to the current position;
  6. Repeat steps 2-5.

Complete example: arrow to mouse

/**
 *Arrow to mouse
 * */
window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const mouse = utils.captureMouse(canvas);
  const arrow = new Arrow();
  //Set elastic coefficient
  const spring = 0.02;
  //Initialization speed
  let vx = 0;
  let vy = 0;
  //Reduction factor
  const friction = 0.95;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    //Calculate the relative distance between the mouse and the arrow
    const dx = mouse.x - arrow.x;
    const dy = mouse.y - arrow.y;
    //Find the angle of the arrow pointing to the mouse
    const angle = Math.atan2(dy, dx);
    //Bounce according to distance
    const ax = dx * spring;
    const ay = dy * spring;
    //Sets the angle of the arrow
    arrow.rotation = angle;
    //Add the decomposed acceleration to the two axis velocities of the arrow
    vx += ax;
    vy += ay;
    //Cutting speed
    vx *= friction;
    vy *= friction;
    //Add the decomposed speed to the two axes of the arrow
    arrow.x += vx;
    arrow.y += vy;
    //Redraw arrow
    arrow.draw(context);
  }());
};