xxxxxxxxxx
139
let particles = [];
const numParticles = 100;
let magnetActive = false;
let magnetStrength = 1000;
function setup() {
createCanvas(800, 600);
// Initialize particles in a pool at the bottom
for (let i = 0; i < numParticles; i++) {
particles.push(new Particle(
random(width),
random(height/2, height),
random(2, 4)
));
}
}
function draw() {
background(240);
// Draw magnet indicator
drawMagnet();
// Update and display particles
for (let particle of particles) {
// Apply gravity
let gravity = createVector(0, 0.2);
particle.applyForce(gravity);
// Apply magnetic force if active
if (magnetActive) {
let magnetPos = createVector(mouseX, mouseY);
let magneticForce = particle.calculateMagneticForce(magnetPos);
particle.applyForce(magneticForce);
}
particle.update();
particle.checkEdges();
particle.display();
}
}
function mousePressed() {
magnetActive = true;
}
function mouseReleased() {
magnetActive = false;
}
function drawMagnet() {
push();
translate(mouseX, mouseY);
if (magnetActive) {
fill(255, 0, 0);
// Draw magnetic field lines
for (let angle = 0; angle < TWO_PI; angle += PI/8) {
let x = cos(angle) * 30;
let y = sin(angle) * 30;
line(0, 0, x, y);
}
} else {
noFill();
}
stroke(0);
strokeWeight(2);
circle(0, 0, 20);
pop();
}
class Particle {
constructor(x, y, radius) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.radius = radius;
this.mass = radius;
this.drag = 0.98;
}
calculateMagneticForce(magnetPos) {
// Calculate direction and distance to magnet
let force = p5.Vector.sub(magnetPos, this.pos);
let distance = force.mag();
// Set minimum distance to avoid extreme forces
distance = constrain(distance, 20, 1000);
// Calculate force magnitude using inverse square law
let strength = (magnetStrength * this.mass) / (distance * distance);
force.setMag(strength);
return force;
}
applyForce(force) {
let f = p5.Vector.div(force, this.mass);
this.acc.add(f);
}
update() {
this.vel.add(this.acc);
this.vel.mult(this.drag); // Apply drag
this.pos.add(this.vel);
this.acc.mult(0);
}
checkEdges() {
// Bounce off edges with energy loss
if (this.pos.y > height - this.radius) {
this.pos.y = height - this.radius;
this.vel.y *= -0.6;
}
if (this.pos.y < this.radius) {
this.pos.y = this.radius;
this.vel.y *= -0.6;
}
if (this.pos.x < this.radius) {
this.pos.x = this.radius;
this.vel.x *= -0.6;
}
if (this.pos.x > width - this.radius) {
this.pos.x = width - this.radius;
this.vel.x *= -0.6;
}
}
display() {
// Calculate color based on velocity
let speed = this.vel.mag();
let hue = map(speed, 0, 10, 200, 360);
colorMode(HSB);
fill(hue, 80, 90);
colorMode(RGB);
noStroke();
circle(this.pos.x, this.pos.y, this.radius * 2);
}
}