KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > util > force > RungeKuttaIntegrator


1 package prefuse.util.force;
2
3 import java.util.Iterator JavaDoc;
4
5 /**
6  * Updates velocity and position data using the 4th-Order Runge-Kutta method.
7  * It is slower but more accurate than other techniques such as Euler's Method.
8  * The technique requires re-evaluating forces 4 times for a given timestep.
9  *
10  * @author <a HREF="http://jheer.org">jeffrey heer</a>
11  */

12 public class RungeKuttaIntegrator implements Integrator {
13     
14     /**
15      * @see prefuse.util.force.Integrator#integrate(prefuse.util.force.ForceSimulator, long)
16      */

17     public void integrate(ForceSimulator sim, long timestep) {
18         float speedLimit = sim.getSpeedLimit();
19         float vx, vy, v, coeff;
20         float[][] k, l;
21         
22         Iterator JavaDoc iter = sim.getItems();
23         while ( iter.hasNext() ) {
24             ForceItem item = (ForceItem)iter.next();
25             coeff = timestep / item.mass;
26             k = item.k;
27             l = item.l;
28             item.plocation[0] = item.location[0];
29             item.plocation[1] = item.location[1];
30             k[0][0] = timestep*item.velocity[0];
31             k[0][1] = timestep*item.velocity[1];
32             l[0][0] = coeff*item.force[0];
33             l[0][1] = coeff*item.force[1];
34         
35             // Set the position to the new predicted position
36
item.location[0] += 0.5f*k[0][0];
37             item.location[1] += 0.5f*k[0][1];
38         }
39         
40         // recalculate forces
41
sim.accumulate();
42         
43         iter = sim.getItems();
44         while ( iter.hasNext() ) {
45             ForceItem item = (ForceItem)iter.next();
46             coeff = timestep / item.mass;
47             k = item.k;
48             l = item.l;
49             vx = item.velocity[0] + .5f*l[0][0];
50             vy = item.velocity[1] + .5f*l[0][1];
51             v = (float)Math.sqrt(vx*vx+vy*vy);
52             if ( v > speedLimit ) {
53                 vx = speedLimit * vx / v;
54                 vy = speedLimit * vy / v;
55             }
56             k[1][0] = timestep*vx;
57             k[1][1] = timestep*vy;
58             l[1][0] = coeff*item.force[0];
59             l[1][1] = coeff*item.force[1];
60         
61             // Set the position to the new predicted position
62
item.location[0] = item.plocation[0] + 0.5f*k[1][0];
63             item.location[1] = item.plocation[1] + 0.5f*k[1][1];
64         }
65         
66         // recalculate forces
67
sim.accumulate();
68         
69         iter = sim.getItems();
70         while ( iter.hasNext() ) {
71             ForceItem item = (ForceItem)iter.next();
72             coeff = timestep / item.mass;
73             k = item.k;
74             l = item.l;
75             vx = item.velocity[0] + .5f*l[1][0];
76             vy = item.velocity[1] + .5f*l[1][1];
77             v = (float)Math.sqrt(vx*vx+vy*vy);
78             if ( v > speedLimit ) {
79                 vx = speedLimit * vx / v;
80                 vy = speedLimit * vy / v;
81             }
82             k[2][0] = timestep*vx;
83             k[2][1] = timestep*vy;
84             l[2][0] = coeff*item.force[0];
85             l[2][1] = coeff*item.force[1];
86         
87             // Set the position to the new predicted position
88
item.location[0] = item.plocation[0] + 0.5f*k[2][0];
89             item.location[1] = item.plocation[1] + 0.5f*k[2][1];
90         }
91         
92         // recalculate forces
93
sim.accumulate();
94         
95         iter = sim.getItems();
96         while ( iter.hasNext() ) {
97             ForceItem item = (ForceItem)iter.next();
98             coeff = timestep / item.mass;
99             k = item.k;
100             l = item.l;
101             float[] p = item.plocation;
102             vx = item.velocity[0] + l[2][0];
103             vy = item.velocity[1] + l[2][1];
104             v = (float)Math.sqrt(vx*vx+vy*vy);
105             if ( v > speedLimit ) {
106                 vx = speedLimit * vx / v;
107                 vy = speedLimit * vy / v;
108             }
109             k[3][0] = timestep*vx;
110             k[3][1] = timestep*vy;
111             l[3][0] = coeff*item.force[0];
112             l[3][1] = coeff*item.force[1];
113             item.location[0] = p[0] + (k[0][0]+k[3][0])/6.0f + (k[1][0]+k[2][0])/3.0f;
114             item.location[1] = p[1] + (k[0][1]+k[3][1])/6.0f + (k[1][1]+k[2][1])/3.0f;
115             
116             vx = (l[0][0]+l[3][0])/6.0f + (l[1][0]+l[2][0])/3.0f;
117             vy = (l[0][1]+l[3][1])/6.0f + (l[1][1]+l[2][1])/3.0f;
118             v = (float)Math.sqrt(vx*vx+vy*vy);
119             if ( v > speedLimit ) {
120                 vx = speedLimit * vx / v;
121                 vy = speedLimit * vy / v;
122             }
123             item.velocity[0] += vx;
124             item.velocity[1] += vy;
125         }
126     }
127
128 } // end of class RungeKuttaIntegrator
129
Popular Tags