One canvas animation code file per week

This chapter introduces another animation application, Gravity. Sounds like some mysterious, but many things must not be confused by the surface phenomenon, understand the principle is very simple! Whether it is the object on the earth, or the stars in the universe, there is always an invisible force field between the object and the object, which is why Newton will be hit by an apple, the earth will move around the sun.

In the last chapter we explained the conservation of momentum, which caused a lot of headaches, because that was probably the hardest part of the series. But I always believe in my heart: let oneself uncomfortable, is can let oneself grow, hope you also believe this point! Here’s how to apply gravity to our animations.

1. Gravity

Baidu Baike says:

Any two particles are attracted to each other by a force in the direction of the connecting lines. This gravitational force is proportional to the product of their masses and inversely proportional to the square of their distance, independent of the chemical composition of the two bodies and the kind of medium between them

Simply put, there is an attraction between two objects that satisfies the following expression:

force = G * m1 * m2 / distance^2Copy the code

Where m1 and m2 are the masses of objects, distance is the distance between objects, and G is the gravitational constant, which is a very small value 6.674*10^-11. You can ignore this value in animation. And then finally, the expression becomes 1, 2

force = m1 * m2 / distance^2Copy the code

2. The particle

As usual, first on the renderings:

Notice that we don’t set any speed for the particles in the animation, but the particles are moving. Let’s look at the implementation of the code in detail.

   Copy the code

The code is very simple, and I’m going to focus on the gravity function. In the gravity function, we pass in two objects as parameters partA, partB. First, calculate the distance between the two objects. And then you plug it into the formula to calculate the magnitude of the force.

The gravitational force between the objects is decomposed into the horizontal and the vertical acceleration of the objects, and notice that the decomposition is a little bit cryptic, dx/dist, which is the cosine of theta. Finally, the acceleration of the body is applied to the velocity.

In the movement function, we introduce the multi-object collision detection strategy, which ensures the interaction between particles and improves the efficiency of the program. For detailed analysis of it, you can see the weekly One point Canvas animation — collision detection (2), which is not explained here. The source code file gravity.

2. Add collision detection

Notice the above animation effect, when two particles are very close, there is no collision, if you want to make a collision between two objects, we just need to add collision detection code in the move function!

function move (partA, i) { partA.x += partA.vx; partA.y += partA.vy; for (var partB, j = i + 1; j < numParticles; j++) { partB = particles[j]; checkCollision(partA, partB); // Gravitate (partA, partB); // Gravity}}Copy the code

The code for collision detection is explained in detail in Canvas Animation of the Week — Billiard Sports (2), which is exactly the same. Just take it and use it. I don’t have to explain too much here.

3. The solar system

Since it is gravity, then how little classical solar system! While you can orbit objects without using gravity, you can make them circle or ellipse using simple trigonometric functions. But that’s not true. Ok, so here we’re simply taking Mercury, Venus, earth around the sun, and you can add the rest up.

The code is the same as the code with collision effect added above, the only difference is that we only introduce 4 objects, each object has different mass, initial velocity and other properties, for example, the sun’s properties are as follows:

sun.x = canvas.width/2;
sun.y = canvas.height/2;
sun.mass = 10000;
particles.push(sun);Copy the code

The sun has a massive mass of 10,000, and look at the properties of the Earth:

earth.x = canvas.width/2+300; earth.y = canvas.height/2; earth.mass = 1; Earth. Vy = 5.8; Earth. Name = "earth ";Copy the code

The mass of the earth is very small, only 1. And it has a vertical velocity vy, which is to make the earth move in the vertical direction at the beginning, so that the gravitational attraction of the sun on the Earth will make it deviate from the original direction of motion. After proper adjustment, a perfect earth moving in a circle around the sun can be obtained.

Here are two points that I think are important:

First of all, why is it debugged? You can open the source code and try to change the speed of the earth. You will find that as you slow down the earth, the earth will be attracted to itself by the sun, in the same way that airplanes on Earth cannot escape the Earth due to speed limits. When you increase the speed of the Earth, you find that the sun’s gravity is not strong enough to pull the Earth toward itself, and earth escapes the sun’s pull.

Second, why doesn’t the sun move? In our code, you should notice that when applying acceleration to the velocity of an object, we don’t directly add the velocity value to the acceleration, but rather:

partA.vx += ax/partA.mass; PartA. Vy += ay/partA. Mass; partB.vx -= ax/partB.mass; partB.vy -= ay/partB.mass;Copy the code

You take the magnitude of the acceleration divided by the mass of the object. So you find that the sun doesn’t move because it’s so massive that other planets have little effect on it. Is that quite plausible? You can try to make the mass of the Earth very large, and you will find that the sun moves too!

For the code, see: orbit.html

4. Particle Garden

Different from the particle effect at the end of the last chapter “Canvas Animation of a Week” — Billiard Movement (2), taste what the particle effect of gravity is like.

Because the computer is so bad, you may see a bit of a lag, but the actual effect is much smoother. There’s nothing hard about the code, we’re just going to wire objects if the distance between them is less than a certain value.

if (dist < minDist) { context.save(); The context. StrokeStyle = "rgba (255255255, 3)"; context.beginPath(); context.moveTo(ballA.x, ballA.y); context.lineTo(ballB.x, ballB.y); context.closePath(); context.stroke(); context.restore(); }Copy the code

See node-garden-line.html for the code

5. To summarize

Important formulas in this chapter:

function gravitate(partA, partB){
     var dx = partB.x - partA.x;
     var dy = partB.y - partA.y;
     var distQ = dx*dx + dy*dy;
     var dist = Math.sqrt(distQ);
     var F = (partA.mass * partB.mass)/distQ;
               
     var ax = F * dx/dist;
     var ay = F * dy/dist;
               
     partA.vx += ax/partA.mass;
     partA.vy += ay/partA.mass;
     partB.vx -= ax/partB.mass;
     partB.vy -= ay/partB.mass;
 }Copy the code

This concludes the first half of Canvas animation series. If you have mastered all of these, you can make a lot of beautiful animation effects with canvas API. In the next part, we will introduce the dark technology of Canvas animation — 3D. Either webGL or 2D Canvas for 3D effects, stay tuned!