|
Author |
Topic: Help: Springs, instability, and explosions! (Read 2156 times) |
|
mflux
|
Re: Help: Springs, instability, and explosions!
« Reply #15 on: Mar 4th, 2005, 11:08am » |
|
Hey guys! Thanks for all your guidance! I think I got it. It's not Runge-Kutta "as described", but I took the concept and tried it myself and it more or less works! My spring sets now have a MUCH higher threshold for density than before (on the order of about 10 times..) Check it out: http://users.design.ucla.edu/~mflux/p5/phenome/applet/ Press C to cycle through random spring sets. The old version would blow up as soon as a high density spring set is created. Now it's quite stable, with the exception of a few monstrous spring sets... My semi-Runge-Kutta code is pretty simple. Here is the Euler version: Code: position displace(float angle,float magnitude) //returns the position displaced by an angle and distance { float ra=radians(angle); position newP=new position(x,y); newP.x+=(cos(ra)*magnitude); newP.y-=(sin(ra)*magnitude); return newP; } |
| Here is the semi-Runge-Kutta version: Code: position displaceRK(vector v) { position newP=new position(x,y); position k[]=new position[int(rkIterations)]; k[0]=new position(newP); for(int i=1;i<rkIterations;i++) { k[i]=new position(k[i-1].displace(v.a,v.m/rkIterations)); } float kx=0; float ky=0; for(int x=0;x<rkIterations;x++) { kx+=2*k[x].x; ky+=2*k[x].y; } kx=kx/rkIterations/2; ky=ky/rkIterations/2; vector vec=new vector(newP,new position(kx,ky)); vec.m*=rkIterations/rkIterations*2; newP=newP.displace(vec.a,vec.m); return newP; } |
| It allows for multiple orders of Runge-Kutta. I think... The difference is that, from all my reading about Runge-Kutta, they have numerical weights to the middle numbers. So for example... In Runge-Kutta you would have p1 (initial point), 2*p2 (midpoint solved from p1), 2*p3 (midpoint solved from p2), and p4 (the endpoint). Next, you add these together and divide... (p1+2*p2+2*p3*p4)/6 At least that's what's called a "fourth order Runge-Kutta". Described better here for math geeks: http://mathworld.wolfram.com/Runge-KuttaMethod.html However... the results I get from that are erratic. The whole idea of averaging these numbers out is so that the last point (where p4 is) would have a minimal amount of numerical error. Wouldn't multiplying 2 to the midpoints, in addition to having TWO midpoints when averaging, get you something that's NOT P4? That's something I don't really understand about the descriptions of Runge-Kutta. At any rate, the technique I'm using is more-or-less working. If anyone wants to enlighten me further on Runge-Kutta please do so because I'm very curious now...
|
« Last Edit: Mar 4th, 2005, 11:15am by mflux » |
|
|
|
|
mflux
|
Re: Help: Springs, instability, and explosions!
« Reply #16 on: Mar 4th, 2005, 11:54am » |
|
Ah nevermind. It works, but I was being stupid. My code was actually decreasing spring tension, thus giving the illusion that it's working. I thought the slow-down was due to calculation but it was not. It now actually does Runge-Kutta, by the book! Woot: http://users.design.ucla.edu/~mflux/p5/phenome/applet/ Code: position displaceRK(vector v) { position newP=new position(x,y); position k1=newP; position k2=k1.displace(v.a,v.m/2); position k3=k2.displace(v.a,v.m/2); position k4=k3.displace(v.a,v.m/2); float kx=(k1.x+2*k2.x+2*k3.x+k4.x)/6; float ky=(k1.y+2*k2.y+2*k3.y+k4.y)/6; vector vec=new vector(newP,new position(kx,ky)); newP=newP.displace(vec.a,vec.m); return newP; } |
| I can't believe how easy that was. I'm smacking myself in the head right now. Ofcourse now it's possible to write an N-order Runge-Kutta...
|
« Last Edit: Mar 4th, 2005, 12:33pm by mflux » |
|
|
|
|
Quasimondo
|
Re: Help: Springs, instability, and explosions!
« Reply #17 on: Mar 4th, 2005, 6:36pm » |
|
Bravo - great work! And isn't it amazing how the code looks immediately more attractive?
|
Mario Klingemann | Quasimondo | Incubator | côdeazur
|
|
|
|