• Advertisement
Sign in to follow this  

Spring Question

This topic is 4547 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all. I have a question about spring equation. I am making a fabric simulation and I wrote a simple spring simulation code to simulate spring and dashpot (the one which stop spring from moving too much, something like shock absorber). The code is here:
spring_dash_f.set(0,0,0);
vec3 spring_dash = box_array[Box_n2]->particles1[name1]->pos - box_array[Box_n1]->particles1[name2]->pos; 
float length = spring_dash.GetLength();
float displacement = length - originalLength; 
vec3 spring_dashN = spring_dash.GetNormalised();
spring_dash_f = spring_dashN*(((displacement)*K));
int extra = 1;


box_array[Box_n1]->particles1[name2]->addforce(box_array[Box_n1]->particles1[name2]->getforce() + spring_dash_f * extra);
box_array[Box_n1]->particles1[name1]->addforce(box_array[Box_n2]->particles1[name1]->getforce() - spring_dash_f * extra); 

As you can see I calculate the spring force and then apply it to the two masses, which are connected to spring. When I run the simulation, the springs get stretched too much due to masses and because I am using Euler I can't increase the K more than 90. Now the question is here: How can I make the springs to get stretched for example between 1 and 1.2 units? I mean how can I enforce the springs not to get stretched too much or gets too small? This is also very important as fabric becomes more realistic. Thank you so much in advance.

Share this post


Link to post
Share on other sites
Advertisement
Increase K and use a better integrator (Runge-Kutta IV or an implicit scheme).
Increase the friction and decrease the time step.

Share this post


Link to post
Share on other sites
Yes, that is correct, but I have seen some people who use Euler but he wrote a function that enforce spring to get streched, basically this function keeps the lenght between the desire numbers.
Is there any of you who know what I can do to keep the spring lenght between a specific range?

Thanks

Share this post


Link to post
Share on other sites
In the linked article below, Mr. Gaffer shows the basics of springs(which I guess you already know).
But near the end of the article he mention that he will show in a future article how to handle what you are talking about, I guess.
Perhaps you could contact him and ask for a little preview?

Springs

Share this post


Link to post
Share on other sites
I did email him and invited him here, I hope he come here and give us some feedbacks.
meanwhile it would be great if anybody else know how we can do this?!

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
I did email him and invited him here, I hope he come here and give us some feedbacks.
meanwhile it would be great if anybody else know how we can do this?!


i think the technique youre looking for works like this:

instead of using euler, a (velocity-less) verlet integrator is used, which is just as simple to code. then, instead of applying forces, constrains are enforced by altering positions of the masses to conform to the springs length. this is repeated until the solution converges.

i believe there is a paper by some guy who worked on hitman who explains this technique. google for hitman physics and youre bound to find something.

Share this post


Link to post
Share on other sites
One solution is to move the particles with some algorithms to correct the elongations; this one is harder than it seems because if you move a particle you modify also the spring length of the neighbours and it may introduce instability in the integration or even further over elongations.
In other words the risk is to introduce a cascade or a "domino" effect of over elongations.
However this method can be interesting to explore.

Another solution is to use a non linear spring coefficient: small when the spring is near its rest length, big when the spring is compressed or elongated.
This one is interesting because it simulates the physic behaviour of a real cloth in which the stretch resistance is something similar to an exponential; the drawback is that the problem becomes more "stiff" so to integrate the equation you have to reduce drastically the time step and/or modify the integrator.

When the problem is so stiff you probably cannot use Euler/Verlet but use at least the classic Runge-Kutta IV. RK IV is very simple to program but it does not work very well with stiff problems.
I could suggest you to use an implicit integrator but they are very hard to program although they are very very fast (you can use a GREATER time step). Consider that almost every real-time cloth simulation ( and not only ) use implicit schemes; be sure that with Euler and Verlet you will go not so far in these kind of problems (although they can be good enough in different situations)

Implicit schemes are usually simpler when you use a non physical correct model (like those used in demos and in games) because you can simplify the equations to program the solver.

Share this post


Link to post
Share on other sites
What would be the best and the most stable system to simulate fabric in realtime?
mass-spring ? or something else?

Share this post


Link to post
Share on other sites
Thank you so much John Schultz.
When I finished reading the articles I became really confused over the whole thing, verlet and fixed time step and (e.g. "10% delta rule") :(

you were talking about:
---
|\|
---
which is look really promising. I think this structure is a lot better than the other one.
Could you please tell me what stepps I should take in order to have a fabric simulation running, using above structure?
I know you have talked about it on other threads but could you just sum up the whole thing so I will have a clearer idea about it.
I suppose:
1-I should have a verlet integrator running (currently Euler).
2-fix my time step, I am currently using this:

float t = 0.0f;
float dt = 0.24f;
float currentTime = 0.0f;
float accumulator = 0.0f;
const float newTime = time();
float deltaTime = newTime - currentTime;


if (deltaTime>0.24f)
//continue;
deltaTime = 0.24f;

currentTime = newTime;

accumulator += deltaTime;

while (accumulator>=dt)
{
updateScene (0.024);//when i put dt here, the whole
//thing explode
accumulator -= dt;
t+=dt;
}


3- change my structure to above one from:

A--B--C between A and C I have folding spring as well.
|\/|\/|
|/\|/\|
-------

Thank you

Share this post


Link to post
Share on other sites
I tried to use Verlet in my program but it didnt work, my code for Eular is:
Eualr

vec3 accl = grav + final_f + extra/mass;
velo = velo + accl * (timestep);
dis = velo * (timestep) + accl * (timestep*timestep)/2;
pos = pos + dis;

resetforce();



Verlet

float dt2 = timestep*timestep;
vec3 accl = final_f + extra /mass;
velo = pos - m_prevPos + accl * dt2;
m_prevPos = pos;
pos = pos + velo;

resetforce();




When I move to verlet the whole system explode, masses fly all over the space, what is wrong with my code?
I didnt use any springs or constraints, masses are perfect when I use Eular but with didnt work with verlet :(

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
When I move to verlet the whole system explode, masses fly all over the space, what is wrong with my code?


"vec3 accl = final_f + extra /mass;"
didnt you forget parenthesis there?

Share this post


Link to post
Share on other sites
No it didnt work.
I tried this and it didnt work.

vec3 total = grav+final_f+extra;
float dt2 = timestep * timestep;
vec3 accl = vec3(0,0,0) + total / mass;
velo = pos - m_prevPos + accl * dt2;
m_prevPos = pos;
pos = pos + velo;

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
No it didnt work.
I tried this and it didnt work.
*** Source Snippet Removed ***


There seems to be a problem with your velocity calculation. Try this


vec3 total = grav+final_f+extra;
float dt2 = timestep * timestep;
vec3 accl = vec3(0,0,0) + total / mass;
del = pos - m_prevPos;
m_prevPos = pos;
pos = pos + del + accl * dt2;
velo = (pos - m_prevPos) / timestep;


-Josh

P.S. Apologies for not using the code snippet thing, but I can't get the plus symbol to appear. Can anyone tell me why that is?

Share this post


Link to post
Share on other sites
Quote:
Apologies for not using the code snippet thing, but I can't get the plus symbol to appear. Can anyone tell me why that is?
I don't know why, but +'s are filtered in preview mode. They do however show up in the actual post.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
Apologies for not using the code snippet thing, but I can't get the plus symbol to appear. Can anyone tell me why that is?
I don't know why, but +'s are filtered in preview mode. They do however show up in the actual post.


Cheers, jyk! :)

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
When I finished reading the articles I became really confused over the whole thing, verlet and fixed time step and (e.g. "10% delta rule") :(


The "10% rule" means that if the spring length changes more than 10% of its length, don't apply a spring force. Instead, treat the spring (link) as a Verlet rigid constraint (which is 100% stable). "10%" was taken from the ILM paper; I used values based on testing the system (including just clamping force/accel to a maximum value). Thus "10%" is arbitrary (depends on timestep, etc.).

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
My verlet is not working dear John,
Please please will you give me a hand to make it work?

Thank you


Hi bargesteh,

Sorry I can't spend more time on this right now. If you look at the post in my link above where I list items 1., 2., 3., (starting with a particle), you should be able to get your system to work by following those steps.

Share this post


Link to post
Share on other sites
Thank you john, I will try to figure it out somehow.

Is there any body else who can tell me how I can use Verlet in a simple mass-spring system?

The only thing i want to do now is to use verlet in the same as euler where I can put fee masses above ground and then realease them and let gravity to hangle them.

is there anybody who can give me a pseudo code?

I can use simple Euler to drop a mass but when I use the Verlet the whole thing explode.

Thank you.

Share this post


Link to post
Share on other sites
Quote:
Original post by bargasteh
is there anybody who can give me a pseudo code?


Did you try the suggestion I made above?


-Josh


Share this post


Link to post
Share on other sites
Yes, I did but the result was almost the same.
when I use this euler code program works fine.

float dt2 = timestep*timestep;
vec3 accl = grav + getforce() + extra/mass;
velo = velo + accl * (timestep);
dis = velo * (timestep) + accl * (dt2)/2;
pos = pos + dis;

I commented the above code and then put this instead:

vec3 total = grav+final_f+extra;
float dt2 = timestep * timestep;
vec3 accl = vec3(0,0,0) + total / mass;
vec3 del = pos - m_prevPos;
m_prevPos = pos;
pos = pos + del + accl * dt2;
velo = (pos - m_prevPos) / timestep;



do I need to make any other changes in my program to get verlet working apart from above code or not?

As I said I am not bothered about spring(constraint) right now, what I am bothered is to move my masses realisticly.

Any help?

Share this post


Link to post
Share on other sites
Well, that sounds odd. Can you tell us what values you are using for the mass and the spring constant? In your original post you mention that you have a dashpot in your model, is that still the case?


-Josh

Share this post


Link to post
Share on other sites
I am using this for my spring force and I am not using any dashpot:

for(int j=0; j<2; j++) {
vec3 delta = box_array[Box_n2]->particles1[name1]->pos - box_array[Box_n1]->particles1[name2]->pos;
float deltalength = delta.GetLength(); //lenght between two masses
float diff=(deltalength-originalLength) / deltalength * K;

box_array[Box_n1]->particles1[name2]->addforce(box_array[Box_n1]->particles1[name2]->getforce() + delta * 0.5 * diff);
box_array[Box_n2]->particles1[name1]->addforce(box_array[Box_n2]->particles1[name1]->getforce() - delta * 0.5 * diff);
}



I put value k = 100 for spring. My problem is not really spring right now, I remove springs between my masses to see what happen to my masses when I shift to Verlet. it seem that there is something wrong with my Verlet code or I have to remove something. someone else has mentioned that I shouldnt include gravity in my code when I am using Verlet?! is it true?
if you look at my code below:


vec3 total = grav+final_f+extra;
float dt2 = timestep * timestep;
vec3 accl = vec3(0,0,0) + total / mass;
vec3 del = pos - m_prevPos;
m_prevPos = pos;
pos = pos + del + accl * dt2;
velo = (pos - m_prevPos) / timestep;



final_f is the previus forces which was applied to masses, extra is wind and grav is gravity force. I think there is something wrong with vec3 total/b].
What is the order of applying forces to mass in Verlet?

Share this post


Link to post
Share on other sites
there are many different verlet variants. search for and try a more common one, the one youre using now might be for some specific purpose or another: or just plain old flawed.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement