I am not sure if I am missing something specific to the toxi library, but I keep getting a ConcurrentModificationException when I try to control my particles in my secondary window via the mouse in my primary window. The crash seems to be random, sometimes it crashes on one click, sometimes I can drag the particles around for a second or two either way I can;t seem to figure it out. Can anyone help, please?
Particles p;
AttractionBehavior mouseAttractorP;
Vec2D mousePos;
FinalPanel tp;
void setup() {
size(1024, 768, P3D);
frameRate(60);
tp = new FinalPanel(400,400);
surface.setTitle("Touch Panel");
}
void draw() {
background(0, 0, 0);
}
void mousePressed() {
mousePos = new Vec2D(mouseX, mouseY);
if (mouseButton == LEFT) {
// create a new attraction force field around the mouse position
mouseAttractorP = new AttractionBehavior(mousePos, 250, 7);
p.physics.addBehavior(mouseAttractorP);
}
if (mouseButton == RIGHT) {
// create a new repulsion force field around the mouse position
mouseAttractorP = new AttractionBehavior(mousePos, -33, -1);
p.physics.addBehavior(mouseAttractorP);
}
}
void mouseDragged() {
// update mouse attraction focal point
mousePos.set(mouseX, mouseY);
}
void mouseReleased() {
// remove the mouse attraction when button has been released
p.physics.removeBehavior(mouseAttractorP);
}
import toxi.geom.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
import toxi.math.*;
import megamu.mesh.*;
class Particles {
final PApplet g;
int NUM_PARTICLES;
VerletPhysics2D physics;
AttractionBehavior mouseAttractor;
float [][] pos;
float eSize;
float xOff;
Delaunay delaunay;
int [] polygons;
Particles(PApplet _p) {
g = _p;
xOff = 0;
NUM_PARTICLES = 666;
eSize = 1;
physics = new VerletPhysics2D();
physics.setDrag(0.7);
physics.setWorldBounds(new Rect(0, 0, width, height));
physics.addBehavior(new GravityBehavior(new Vec2D(-0.00007, -0.0003f)));
for (int i = 0; i<NUM_PARTICLES; i++) {
addParticle();
}
}
void addParticle() {
VerletParticle2D p = new VerletParticle2D(Vec2D.randomVector().scale(133).addSelf(width / 2, height/2));
physics.addParticle(p);
// add a negative attraction force field around the new particle
physics.addBehavior(new AttractionBehavior(p, 13, 0.3f, 3f));
}
void drawParticles() {
// store particles delaunayitions to do delaunay triangulation
pos = new float[NUM_PARTICLES][2];
for ( int i=0; i<NUM_PARTICLES; i++) {
// particle system using verlet integration
VerletParticle2D p = physics.particles.get(i);
g.pushStyle();
g.fill(255, 33);
g.ellipse(p.x, p.y, g.noise(xOff) * 13, g.noise(xOff) * 13);
g.popStyle();
pos[i][0] = physics.particles.get(i).x;
pos[i][1] = physics.particles.get(i).y;
}
}
// delaunay triangulation logic taken from here :
// http://www.openprocessing.org/sketch/43503
void drawLines() {
// delaunay triangulation
delaunay = new Delaunay(pos);
// getEdges returns a 2 dimensional array for the lines
float[][] edges = delaunay.getEdges();
for (int i=0; i<edges.length; i++)
{
// use the edges values to draw the lines
float startX = edges[i][0];
float startY = edges[i][1];
float endX = edges[i][2];
float endY = edges[i][3];
float distance = dist(startX, startY, endX, endY);
// remap the distance to opacity values
float trans = 255-map(distance, 0, 33, 33, 0);
// stroke weight based on distance
// fast invert square root helps for performance
float sw = 3f/sqrt(distance*2);
g.ellipseMode(CENTER);
g.pushStyle();
g.strokeWeight(sw);
g.stroke(g.noise(1)*233);
g.fill(g.random(255), g.random(255), g.random(255));
g.noFill();
g.ellipse(startX, startY, eSize, eSize);
g.popStyle();
//pushStyle();
//stroke(200, 3);
//noFill();
//bezier(startX, startY, endX, mouseY, width/2, mouseY, width/2, height/2);
//popStyle();
}
}
}
class FinalPanel extends PApplet {
int w, h;
public FinalPanel(int _w, int _h) {
super();
w = _w;
h = _h;
PApplet.runSketch(new String[]{this.getClass().getName()}, this);
}
public void settings() {
size(w, h, P3D);
}
public void setup() {
blendMode(ADD);
surface.setTitle("Final Panel");
surface.setLocation(0, 0);
p = new Particles(this);
}
void draw() {
background(0);
p.physics.update();
p.drawParticles();
p.drawLines();
}
}