I'm trying to simulate a string using gen~ but I'm really stuck on this.
I'm making a simulation of a string using the gen~ patcher and its codebox object. However, it's seems to not work completely. I am not a programmer, so I'm struggling quite a bit. I've been working at this for a good while now and I think my understanding is just not deep enough to be able to figure out what's going on. So I would really like help from someone more knowledgeable that me to help me figure this out.
So here's my code:
Param tension();
Data vel();
Data pos();
Data nvel();
Data npos();
Param Dx2();
Param eff();
Param read();
end = dim(pos);
for(i=0;i<=end;i+=1) {
v = eff*peek(vel, i) + tension*((peek(pos, i+1) + peek(pos, i-1)) -2*peek(pos, i))/samplerate/Dx2;
poke(nvel, v, i);
p = peek(pos, i) + peek(vel, i)/samplerate;
poke(npos, p, i);
}
for(j=0;j<=end;j+=1){
np = peek(npos, j);
poke(pos, np, j);
nv = peek(nvel, j);
poke(vel, nv, j);
}
What it's supposed to do:
First I'm getting acceleration for each 'node' (each sample of the Data object), by looking at the difference between the pos value of the 'node' we test and the 'node' to its left and its right. Then this get's divided by the sample-rate and added to the vel, which I'm storing temporarily in a 'buffer' to later replace the old values. After that we need divide the velocity by the sample-rate and add it to the pos value. This also get's its own 'buffer' treatment. also there's some coefficients like tension etc, but their not really important right now.
Here's an equation which might help you understand:

The problem:
I need to always input a signal to keep it going it would seem. My end goal is to be able to send a pulse to change the pos value on some arbitrary point and be able to let the string hum out. Right now it stops updating when I don't give it a signal. Any ideas? Also it doesn't process the other indexes in I don't peek all of them, which either would require 512 outlets or reading them individually with a counter but I can't do that at sample-rate. There must be a way to tell it to stop cutting corners right?
I've solved the problem! it works now probably cause I decided to use functions instead, which I avoided because you can't use poke in them for some reason.
here's the new code:
position(pos, f, vel, dt){return peek(pos, f) + peek(vel, f)*dt;}
velocity(pos, f, vel, dt, l, m, t){return peek(vel, f) + t*(peek(pos, f+1) + peek(pos, f-1) - 2*peek(pos, f))*dt*l/m;}
dt = 1/samplerate;
l = 512.;
mass=1.;
tension=10.;
loss=0.0001;
inp=in1;
for(f=0;f<=512;f+=1){
v = velocity(pos,f,vel,dt,l,mass,tension);
p = position(pos,f,vel,dt);
if(f==256){v=v+10*inp*dt;}
poke(vel, v*(1.-loss), f, 0, 0);
poke(pos, p, f, 0, 0);
}
out1=peek(pos, 0);
out2=peek(pos, 256);
out3=peek(pos,511);