xxxxxxxxxx
int nodeCount = 30;
int nodeLines =10;
Node[] myNodes = new Node[nodeCount*nodeLines];
Attractor myAttractor1;
Attractor myAttractor2;
void setup() {
size(600, 600);
background(255);
smooth();
fill(0);
for (int y=0; y<nodeLines; y++) {
for (int x =0; x<nodeCount; x++) {
myNodes[y*nodeCount+x]=new Node(x*(width/nodeCount), 250+y*10);
myNodes[y*nodeCount+x].damping=0.01;
}
}
myAttractor1 = new Attractor(width/2, height/2);
myAttractor2 = new Attractor(width/2, height/2);
}
void draw() {
background(255);
beginShape();
for (int i = 0; i<myNodes.length; i++) {
if (mousePressed) {
myAttractor1.attract(myNodes[i]);
} else {
myAttractor2.strength=0.2;
myAttractor2.attract(myNodes[i]);
}
vertex(myNodes[i].x, myNodes[i].y);
myNodes[i].update();
}
endShape(LINE);
}
class Node extends PVector {
PVector velocity = new PVector();
float minX=5, minY=5, maxX=width-5, maxY=height-5;
float damping = 0.1;
Node(float _x, float _y) {
x = _x;
y = _y;
}
void update() {
x+=velocity.x;
y+=velocity.y;
if (x<minX) {
x=minX-(x-minX);
velocity.x=-velocity.x;
}
if (x>maxX) {
x=maxX-(x-maxX);
velocity.x=-velocity.x;
}
if (y<minY) {
y=minY-(y-minY);
velocity.y=-velocity.y;
}
if (y>maxY) {
y=maxY-(y-maxY);
velocity.y=-velocity.y;
}
velocity.x*=(1-damping);
velocity.y*=(1-damping);
}
}
class Attractor {
float x=0, y=0;
// radius of impact
float radius = 600;
// strength: positive for attraction, negative for repulsion
float strength = -1;
// parameter that influences the form of the function
float ramp = 0.5; //// 0.01 - 0.99
Attractor(float _x, float _y) {
x = _x;
y = _y;
}
void attract(Node theNode) {
float dx = x-theNode.x;
float dy = y-theNode.y;
float d=mag(dx, dy);
if (d>0 && d<radius) {
// calculate force
float s = pow(d / radius, 1 / ramp);
float f = s * 9 * strength * (1 / (s + 1) + ((s - 3) / 4)) / d;
// apply force to node velocity
theNode.velocity.x += dx * f;
theNode.velocity.y += dy * f;
}
}
}