Tornado Particle System

An animated tornado using a 3D particle system.
Languages: C, C++, HTML, and CMake.

Proposal

I am proposing animating a tornado using a 3D particle system. This project will involve creating a cone shape of 3D particles. Each “ring” within the tornado will have a ring of spinning 3D particles. These particles will have varied speeds so that they are not uniform; however, particles in the ring will rotate at about the same speed. “Rings” toward the bottom of the tornado will spin faster than those towards the top. The same applies to the radius of the “rings.” “Rings” will have smaller radius towards the bottom of the tornado and “rings” will have a 3D particle set around that radius.

Video Demonstration

What was Done

For this project I used the particle system skeleton from one of my previous projects. Because of this, many of the struct properties from my previous project carry over, but not all of them. With the skeleton, I was able to create a particle system contained within a cone-shaped tornado.

There are two keyboard functions that were implemented. The first is a DoColors function that organizes sections into colored bands. The particle’s default colors are random and are generated when the particle is initialized. The keyboard functions allow the tornado to display colored bands by toggling “c” or “C” as seen in Figure 1.

Figure 1

The second added function allows you to alter the shape of the tornado. Pressing 1, 2, 3, or 4 on the keyboard will change the height to radius ratio of the tornado, making it skinnier or wider. The ratio can have a value of 1, 2, 3, 4 and results in the tornados shown in Figure 2.

Figure 2

Proposal vs. Final Product

I proposed the tornado would split off into “ring” sections where particles assigned to a section could only move within that section. However, the final product ended up having particles move from the bottom of the tornado to the top for a better tornado effect. The y-coordinate in every particle is increased by their y-velocity attribute and a random offset.

Figure 3

This also meant I had to add the “life” attribute to each particle. If all the particles rose to the top, there would be no bottom half. Because of this, there is a life/death system implemented into the program. If one of the particles reaches the max height of 200, the particle disappears and a new particle is made at the bottom of the tornado.

Challenges and Solutions

The most time-consuming challenge was figuring out how to contain the particle system within a cone shape and have the center of the tornado be empty. I experimented with a collision avoidance system using an invisible cone that would contain the particle system. However, I found a much more elegant solution using a mathematical equation. Forming the particles into rings was simple using the parametric equations 𝑥 = sin (𝜃) and 𝑦 = cos (𝜃).

Figure 4

Using the equation in Figure 4, you can get the x and z coordinate along a circle with a given radius. However, this made the tornado form a cylinder shape. I tried many ways to manipulate the radius as a particle’s y coordinate increased to get a cone shape. The method I found best was scaling the radius by the velocity of y. This makes it so that each particle’s radius increases at the same rate as y increases.

Figure 5

Figure 6 shows how I scaled the height increase rate by the global variable “tornadoSlope”. This variable has a default value of 2, but changing it with the 1, 2, 3, and 4 keypresses will change its value to those respective numbers. This this produces 4 different sized tornados.

Lessons Learned

There are several lessons that I can take away from this project. The first is learning about collision avoidance systems and how they may be implemented in future projects. Although this kind of system was not needed for this project, I now have a better understanding on how to approach them. The second is a much-needed refresher on parametric equations in relation to circles. Finally is a better familiarity of particle systems. I feel that I understand how to approach and manage emitter, displayer, and updating functions in an effective way.


Want to View My Code?

Click here to access the Google Drive folder containing this project.

Contact Me.

Email me at sissone820@gmail.com.