// Multiple attractor by Jonny Stutters // This code is public domain, do as you like with it import oscP5.*; import netP5.*; PVector[] wells = new PVector[6]; float[][] fieldStrength = new float[500][500]; PVector[][] field = new PVector[500][500]; Particle roids[] = new Particle[15]; PGraphics pg = createGraphics(500, 500, P2D); int[] nmap = new int[] {0, 3, 7, 10}; OscP5 oscP5; NetAddress sc; void setup() { oscP5 = new OscP5(this, 12000); sc = new NetAddress("127.0.0.1", 57120); frameRate(15); wells[0] = new PVector(100, 100); wells[1] = new PVector(400, 100); wells[2] = new PVector(400, 400); wells[3] = new PVector(100, 400); wells[4] = new PVector(225, 350); wells[5] = new PVector(225, 150); for(int x = 0; x < 500; x++) { for(int y = 0; y < 500; y++) { field[x][y] = new PVector(0, 0); } } for(int i = 0; i < roids.length; i++) { roids[i] = new Particle(new PVector(int(random(100, 400)), int(random(100, 400))), new PVector(0, 0), noteMap(i)); } size(500, 500, P2D); noStroke(); for(int i = 0; i < wells.length; i++) { plotField(wells[i]); } println("Plotting complete"); float[] minStrengths = new float[500]; for(int i = 0; i < 500; i++) { minStrengths[i] = min(fieldStrength[i]); } float minStrength = min(minStrengths); println(minStrength); println(min(fieldStrength[0])); println("Drawing..."); pg.beginDraw(); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { float s = (fieldStrength[x][y] - minStrength) * 40; pg.stroke(int(constrain(s, 0, 255))); pg.point(x, y); } } pg.endDraw(); noStroke(); fill(255, 0, 0); } int noteMap(int i) { int oct = 0; if(i > nmap.length) { oct = int((float)i / (float)nmap.length) * 12; } return(oct + nmap[i % nmap.length] + 36); } void draw() { background(0); image(pg, 0, 0); for(int i = 0; i < roids.length; i++) { roids[i].update(); roids[i].draw(); OscMessage msg = new OscMessage("/attractors"); msg.add(roids[i].note); for(int j = 0; j < wells.length; j++) { msg.add(constrain(roids[i].distance(j), 0.1, 200)); } msg.add(roids[i].speed()); oscP5.send(msg, sc); } } void plotField(PVector w) { float f = 0, d = 0; for(float x = 0; x < width; x++) { for(float y = 0; y < width; y++) { PVector p = new PVector(x, y); d = p.dist(w); if(d != 0) { f = log(d / 100); fieldStrength[int(x)][int(y)] += f; } p.sub(w); p.limit(f / 4); p.mult(-1); field[int(x)][int(y)].add(p); } } } void mouseClicked() { for(int i = 0; i < roids.length; i++) { roids[i] = new Particle(new PVector(int(random(mouseX - 10, mouseX + 10)), int(random(mouseY - 10, mouseY + 10))), new PVector(0, 0), noteMap(i)); } } class Particle { PVector loc, vel; float distances[] = new float[wells.length]; int note; Particle(PVector location, PVector velocity, int n) { loc = location.get(); vel = velocity.get(); note = n; } float distance(int w) { return distances[w]; } float speed() { return vel.mag(); } void update() { vel.add(field[int(loc.x)][int(loc.y)]); loc.add(vel); if(loc.x > 499) { loc.x = 0; } else if(loc.x < 0) { loc.x = 499; } if(loc.y > 499) { loc.y = 0; } else if(loc.y < 0) { loc.y = 499; } for(int i = 0; i < wells.length; i++) { distances[i] = loc.dist(wells[i]); } } void draw() { ellipse(loc.x, loc.y, 5, 5); } }