Hey
So I have been working on simulation of water in 2 dimensions. It is comprised of nodes that are attached by “springs” to their neighbors and to the “water level”. it works fine, but it behaves differently on either side of a perturbation. I understand why, I think the updating is working twice on the next element in line (or something like that) and is effectively causing extra drag on one side. I tried some naive solutions but nothing has worked. any input is appreciated!
int num_of_springs = 101;
Spring[] springs = new Spring[num_of_springs];
void setup() {
size(1200, 640);
fill(255, 126);
for (int i = 0; i<=springs.length-1; i++) {
springs[i] = new Spring(i*width/num_of_springs+20, height/2, 0, 80, .99, 0.99); //(xpos, ypos, gravity, mass, damping, spring_constant)
}
}
void draw() {
background(0);
line(0, height/2, width, height/2);
for (int i = 0; i<=springs.length-1; i++) {
if (i==0) {
springs[0].update(springs[0].x, springs[1].y);
springs[0].update(springs[0].x, height/2);
} else if (i==springs.length-1) {
springs[springs.length-1].update(springs[springs.length-1].x, springs[springs.length-2].y);
springs[springs.length-1].update(springs[springs.length-1].x, height/2);
} else {
springs[i].update(springs[i-1].x, springs[i-1].y);
springs[i].update(springs[i+1].x, springs[i+1].y);
springs[i].update(springs[i].x, height/2);
}
springs[i].display();
}
if (keyPressed) {
if (key == ' ') {
springs[springs.length/2].vy = 10;
}
}
}
class Spring {
float vx, vy;
float x, y;
float gravity = 0;
float mass = 0;
float spring_constant = 0;
float damping = 0;
float target_x;
float target_y;
Spring(float xpos, float ypos, float gravity, float mass, float damping, float spring_constant) {
x = xpos;
y = ypos;
this.gravity = gravity;
this.mass = mass;
this.spring_constant = spring_constant;
this.damping = damping;
}
void update(float target_x, float target_y) {
line(x, y, target_x, target_y);
this.target_x=target_x;
this.target_y=target_y;
float forceX = (target_x - x) * spring_constant;
float ax = forceX / mass;
vx = damping * (vx + ax);
x += vx;
float forceY = (target_y - y) * spring_constant;
forceY += gravity;
float ay = forceY / mass;
vy = damping * (vy + ay);
y += vy;
if (abs(vy) < 0.01) {
vy = 0.0;
}
if (abs(vx) < 0.01) {
vx = 0.0;
}
}
void display() {
fill(255, 100);
stroke(255);
line(x, y, target_x, target_y);
ellipse(x, y, 10, 10 );
noFill();
}
}