xxxxxxxxxx
207
let t = -6;
let origin;
let scalingFactor = 80;
let wind;
let windSlider;
let noiseSlider;
let noiseOff = 0;
let numParticles = 3;
let particles = [];
let equationSet = 1;
let lifetime = 500;
let timeOffsets = [-0.1, 0, 0.1];
function setup() {
createCanvas(windowWidth, windowHeight, SVG);
origin = createVector(width / 2, height / 2);
noFill();
colorMode(HSB);
//background(10); // Set dark background
let canvasBottom = height + 20;
let button1 = createButton("1");
button1.position(10, canvasBottom);
button1.mousePressed(() => switchEquation(1));
let button2 = createButton("2");
button2.position(50, canvasBottom);
button2.mousePressed(() => switchEquation(2));
let button3 = createButton("3");
button3.position(90, canvasBottom);
button3.mousePressed(() => switchEquation(3));
let downloadButton = createButton("Download Image");
downloadButton.position(10, canvasBottom + 40);
downloadButton.mousePressed(downloadImage);
let refreshButton = createButton("Refresh Canvas");
refreshButton.position(140, canvasBottom + 40);
refreshButton.mousePressed(refreshCanvas); // Refreshes the canvas
// Wind slider with only 3 states (1 = left, 2 = no wind, 3 = right)
windSlider = createSlider(1, 3, 2);
windSlider.position(10, canvasBottom + 80);
noiseSlider = createSlider(0, 1, 0, 0.1);
noiseSlider.position(10, canvasBottom + 110);
let windLabel = createDiv('Wind');
windLabel.position(160, canvasBottom + 78);
let noiseLabel = createDiv('Noise');
noiseLabel.position(160, canvasBottom + 108);
initParticles();
}
function draw() {
//frameRate(5);
// Set wind direction based on slider value
let windDirection = windSlider.value();
if (windDirection === 1) {
wind = createVector(-1, 0); // Wind to the left
} else if (windDirection === 2) {
wind = createVector(0, 0); // No wind
} else if (windDirection === 3) {
wind = createVector(1, 0); // Wind to the right
}
let windStrength = abs(wind.x);
// Update and display particles with wind and noise effect
for (let particle of particles) {
particle.update(t, wind, noiseSlider.value(), scalingFactor);
particle.display();
}
t += 0.01;
if (t > 6) {
t = -6;
for (let particle of particles) {
particle.reset();
}
}
noiseOff += 0.01;
}
function initParticles() {
particles = [];
for (let i = 0; i < numParticles; i++) {
if (equationSet === 1) {
particles.push(new Particle(
timeOffsets[i],
(t) => 2.5 * pow(Math.sin(-5 * t), 2) * pow(2, Math.cos(Math.cos(4.28 * 2.3 * t))),
(t) => 2.5 * Math.sin(Math.sin(-5 * t)) * pow(Math.cos(4.28 * 2.3 * t), 2),
lifetime // Particle lifetime in frames
));
} else if (equationSet === 2) {
particles.push(new Particle(
timeOffsets[i],
(t) => 10 * sin(2.78 * t) * round(sqrt(cos(cos(8.2 * t)))),
(t) => 9 * pow(cos(2.78 * t), 2) * sin(sin(8.28 * t)),
lifetime
));
} else if (equationSet === 3) {
particles.push(new Particle(
timeOffsets[i],
(t) => 7 * sin(7.32 * t) / (1 + pow(cos(1.42 * t), 2)),
(t) => 7 * cos(1.42 * t) * pow(sin(7.32 * t), 4),
lifetime
));
}
}
}
function switchEquation(set) {
equationSet = set;
t = -6;
noiseOff = 0;
background(10); // Reset dark background
initParticles();
}
function refreshCanvas() {
t = -6;
noiseOff = 0;
background(10); // Clear with dark background
initParticles(); // Reinitialize particles
}
function downloadImage() {
save("lines.svg");
}
class Particle {
constructor(timeOffset, xEquation, yEquation, lifetime) {
this.timeOffset = timeOffset;
this.prevPos = null;
this.xEquation = xEquation;
this.yEquation = yEquation;
this.lifetime = lifetime; // Lifetime in frames
this.maxLifetime = lifetime; // Store the original max lifetime
}
calculatePosition(currentT, noiseMagnitude) {
let xNoise = map(noise(noiseOff), 0, 1, -noiseMagnitude, noiseMagnitude);
let yNoise = map(noise(noiseOff + 100), 0, 1, -noiseMagnitude, noiseMagnitude);
let x = this.xEquation(currentT) + xNoise;
let y = this.yEquation(currentT) + yNoise;
return createVector(x, y);
}
update(t, wind, noiseMagnitude, scalingFactor) {
if (this.lifetime <= 0) return; // Skip if lifetime is over
let currentT = t + this.timeOffset;
let pos = this.calculatePosition(currentT, noiseMagnitude);
// Apply wind effect
pos.add(wind.copy().mult(1));
pos.mult(scalingFactor);
pos.add(origin);
this.pos = pos;
// Decrease lifetime on every frame
this.lifetime--;
}
display() {
if (this.lifetime <= 0) return; // Skip rendering if lifetime is over
// Calculate alpha based on remaining lifetime
let alphaValue = map(this.lifetime, 0, this.maxLifetime, 0, 255); // Fade from 255 to 0
//let hueValue = map(t, -6, 6, 0, 360); // Changing color over time
let hueValue = random(0, 360)
stroke(hueValue, 100, 100, alphaValue); // HSB color with fading alpha
for (let j = 0; j < 4; j++) {
push();
translate(width / 2, height / 2);
rotate(HALF_PI * j);
translate(-width / 2, -height / 2);
if (this.prevPos) {
line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
}
pop();
}
this.prevPos = this.pos.copy();
}
reset() {
this.prevPos = null;
this.lifetime = this.maxLifetime; // Reset lifetime for new cycle
}
}