反発・誘引するパーティクル
同じ色のパーティクルは反発する. 違う色のパーティクルは引き付け合う.
JavaScriptモードでは重すぎて動かない.
/** * Two Color Particles * * Particles with same color repel each other, particles with different color attract each other. * * @author aa_debdeb * @date 2015/10/02 */ float PARTICLE_RADIOUS = 3.0; float PARTICLE_NUM = 500; float MAX_FORCE = 1.0; float MAX_ACCELERATION = 3.0; float MAX_VELOCITY = 5.0; float VIEW_DISTANCE = 100; ArrayList<Particle> particles; void setup(){ size(500, 500); smooth(); frameRate(24); noFill(); particles = new ArrayList<Particle>(); for(int i = 0; i < PARTICLE_NUM; i++){ particles.add(new Particle()); } } void draw(){ background(0); for(Particle particle : particles){ particle.draw(); } for(Particle particle : particles){ particle.update(); } } class Particle{ PVector position; PVector velocity; boolean isRed; Particle(){ position = new PVector(random(width), random(height)); velocity = new PVector(0.0, 0.0); isRed = random(1) < 0.5 ? true : false; } void draw(){ if(isRed){ stroke(255, 0, 0); } else { stroke(0, 255, 0); } ellipse(position.x, position.y, PARTICLE_RADIOUS * 2, PARTICLE_RADIOUS * 2); } void update(){ PVector acceleration = new PVector(0, 0); for(Particle particle: particles){ if(particle != this){ float relativeX = particle.position.x - position.x; float relativeY = particle.position.y - position.y; if(relativeX > width / 2){ relativeX = relativeX - width; } else if(relativeX < -width / 2){ relativeX = width + relativeX; } if(relativeY > height / 2){ relativeY = relativeY - height; } else if(relativeY < -height / 2){ relativeY = height + relativeY; } PVector relativePosition = new PVector(relativeX, relativeY); float distance = relativePosition.mag(); if(distance < VIEW_DISTANCE){ PVector a; float force = (VIEW_DISTANCE - distance) / VIEW_DISTANCE * MAX_FORCE; float relativeAngle = relativePosition.heading(); if(isRed == particle.isRed){ a = new PVector(force * cos(relativeAngle + PI), force * sin(relativeAngle + PI)); } else { a = new PVector(force * cos(relativeAngle), force * sin(relativeAngle)); } acceleration.add(a); } } } if(acceleration.mag() > MAX_ACCELERATION){ acceleration.normalize(); acceleration.mult(MAX_ACCELERATION); } velocity.add(acceleration); if(velocity.mag() > MAX_VELOCITY){ velocity.normalize(); velocity.mult(MAX_VELOCITY); } position.add(velocity); if(position.x >= width){ position.x -= width; } else if(position.x < 0){ position.x += width; } if(position.y >= height){ position.y -= height; } else if(position.y < 0){ position.y += height; } } }