xxxxxxxxxx
83
class Wave {
constructor(i, radius, direction, offset, col) {
this.velocity = createVector(0, 0); // Determines how fast the wave expands
this.acceleration = createVector(0, 0);
this.mass = random(1, 10); // Mass for the force calculations
this.radius = radius; // Initial size of the wave
this.direction = random(0.005, 0.02) * (i % 2 === 0 ? 1 : -1); // Wave oscillation direction outputting a random value, with opposing directions for every other wave
this.offset = offset; // Used to create variations in the wave/ where the wave starts from
this.theta = random(TWO_PI); // Initial angle or phase for the wave creating the oscillation
this.col = col; // Color of the wave
// Amplitude for wave oscillation, with 30% of waves having high amplitude
if (random(1) < 0.3) {
this.amplitude = random(100, 200); // Higher amplitude for these waves
} else {
this.amplitude = random(3, 10); // Normal amplitude for the rest of the waves
}
}
// Update function adjusts properties each frame
update() {
this.theta += this.direction; // Increase the angle based on direction
this.radius += this.velocity.y; // Adjust wave size
this.velocity.y *= 0.8; // Slow down expansion over time
this.direction += random(-0.005, 0.005); // Vary the oscillation direction slightly as time passes
this.acceleration.mult(0); // Reset acceleration after each frame
}
// Simulate drag force on the wave expansion
drag() {
let drag = this.velocity.copy(); // Copy current velocity
drag.normalize(); // Convert to unit vector (magnitude 1)
drag.mult(-1); // Invert direction
let c = 0.1; // Drag coefficient
let speedSq = this.velocity.magSq(); // Square of speed for quadratic drag force
drag.setMag(c * speedSq); // Scale drag based on squared speed and coefficient
this.applyForce(drag); // Apply the drag force to the wave
}
// Adjust wave velocity based on a given force
applyForce(force) {
let f = p5.Vector.div(force, this.mass); // Force = mass x acceleration
this.acceleration.add(f); // Adjust acceleration based on the force
}
display() {
noFill();
stroke(this.col); // Set the color of the wave using the color specified during wave creation.
strokeWeight(1);
beginShape(); // Start a new shape.
for (let i = 0; i < TWO_PI; i += 0.01) {
// This loop creates the shape of the wave by calculating vertices in a circle around the center.
let overlap = map(noise(this.theta), 0, 1, -5, 5);
// The overlap variable is used to introduce smooth randomness to the wave using Perlin noise
let x =
(this.radius +
overlap +
sin(i * 10 + this.theta + this.offset * PI) * 5) *
cos(i); // Calculate the x position of the vertex.
// Here we use the sin to create oscillations in the wave,
// and we adjust its position based on the wave's current radius, overlap, and offset.
// Multiplying by cos(i) helps to distribute these points in a circular manner.
let y =
(this.radius +
overlap +
sin(i * 10 + this.theta + this.offset * PI) * 5) *
sin(i); // same applies to y
// The structure is the same as for x, but we multiply by sin(i) to distribute the points vertically.
vertex(x, y); // Add this point to the shape being drawn.
}
endShape(CLOSE); // Close the shape, connecting the last vertex to the first.
}
}