xxxxxxxxxx
46
class Particle {
constructor() {
this.pos = createVector(0, random(0, 300), 0); // Start at height 0 to 300
this.radius = map(this.pos.y, 0, 300, 100, 10); // Compute initial radius
this.angle = random(TWO_PI); // Angular position around the tornado
this.noiseOffset = random(1000); // Perlin noise seed
}
update(speedMultiplier) {
// Increment the angular position to simulate swirling
this.angle += (0.02 + noise(this.noiseOffset) * 0.02) * speedMultiplier;
// Update the radius slightly with Perlin noise for organic motion
this.radius += noise(this.noiseOffset) * 5 - 2.5;
// Constrain the radius to a certain bound
this.radius = constrain(this.radius, 20, 500);
// Update height with sinusoidal oscillation (independent of speedMultiplier)
this.pos.y += sin(frameCount * 0.01) * 0.5;
// Wrap height to loop the tornado
if (this.pos.y > 300) {
this.pos.y = 0;
this.radius = map(this.pos.y, 0, 300, 100, 10); // Reset radius
}
// Update the x and z coordinates based on the angle and radius
this.pos.x = this.radius * cos(this.angle);
this.pos.z = this.radius * sin(this.angle);
this.noiseOffset += 0.01 * speedMultiplier;
}
show() {
// Map height to brightness for a gradient effect
let brightness = map(this.pos.y, 0, 300, 50, 100); // Brightness increases with height
fill(0, 0, brightness); // HSB: 0 hue, 0 saturation (gray), brightness
push();
translate(this.pos.x, this.pos.y, this.pos.z);
sphere(3); // Represent the particle as a small sphere
pop();
}
}