The 2nd Order Runge-Kutta formula
shown above is for a single variable x, which would suffice for
determining the motion of a falling object or for an object on spring.
For projectile motion, though, we deal with two coordinates.
We thus need formulas for both vertical (y)
and horizontal (x)
variables:
and
then
Below we show the code for a second order Runge-Kutta
class that generalizes the above formulas to multiple variables.
Array arguments
carry the variables and their derivative. Here we use the name vel,
as in velocity, for the derivatives but these could be derivatives
with respect to a non-time related variable.
The derivative of the velocity comes from an interface
method called Derivable,
shown below. The method modifier static
eliminates the need to create an instance of the class.
RungeKutta2nd.java
|
/**
Carry out the Runge-Kutta 2nd order algorithm. **/
public class RungeKutta2nd
{
/** Calculate as step in the Runge-Kutta 2nd order.
**/
public static void step (double t, double dt,
double
[] var,
double
[] vel,
Derivable
func ) {
double k1_var, k1_vel;
double k2_var, k2_vel;
for (int i=0; i < var.length; i++)
{
k1_var = vel[i] * dt;
k1_vel = func.deriv (i,var[i],vel[i],t)*dt;
k2_var = (vel[i]
+ 0.5*k1_vel)*dt;
k2_vel = func.deriv (i,
var[i]
+ 0.5*k1_var,
vel[i]
+ 0.5 * k1_vel,
t+0.5
* dt) * dt;
var[i] = var[i] + k2_var;
vel[i] = vel[i] + k2_vel;
}
t += dt;
} // step
} // RungeKutta2nd |
Derivable.java
|
public
interface Derivable
{
public double deriv (int i, double pos,
double v,
double
t, double t);
} // Derivable
|
The program below uses the second order Runge-Kutta code above
to solve for the intercept of a projectile with the horizontal plane.
Ignoring air drag (see the exercises),
the horizontal force is zero and the vertical force is a constant.
Note how the class implements the interface and overrides
its method.
RK2ndApplet.java
(Output goes to browser's Java
console.)
|
/**
* This applet uses the second order Runge-Kutta
method
* to solve for the landing point of a projectile.
**/
public class RK2ndApplet extends java.applet.Applet
implements Derivable
{
// Constants
double g = 9.80;// meter per sec**2
double x0 = 0.0;
double y0 = 0.0;
double v0 = 100.0;// initial vel, m/s
double angle = Math.PI/4.0;
// Instance variables
double [] pos = new double[2];
double [] vel = new double[2];
/** Initialize the algorithm. **/
public void init () {
double t;
double total_t;
int n;
double dt = 0.01;
int n_steps = 100000;
pos[0] = x0;
pos[1] = y0;
vel[0] = v0 * Math.cos (angle);
vel[1] = v0 * Math.sin (angle);
t = 0.0;
for (n=0; n < n_steps; n++) {
RungeKutta2nd.step (t,dt,pos,vel,this);
if (pos[1] <= 0.0) break;
}
System.out.println ("After steps ="
+ n);
System.out.println (" x = " + pos[0]);
} // init
/** Implement the interfact method for the derivative
* of the variables. **/
public double deriv (int i, double newVar, double
newVel, double t) {
if (i == 0) {// x variable
return 0.0;
} else { // y variable
return -g;
}
} // deriv
/** Paint message in Applet window. **/
public void paint (java.awt.Graphics g) {
g.drawString ("RK2ndApplet",20,20);
} // pain
/** Run optionally as an application. **/
public static void main (String [] args) {
RK2ndApplet obj = new RK2ndApplet
();
obj.init ();
} // main
} // RK2ndApplet |
The output shows
After steps
=1443
x = 1021.0621920333822 |
This compares to a value of 1020.4 for the analytical
solution.
Exercise : Try
a finer dt
value to see if the intercept makes a better match to the analytical
value.
Exercise : The
program checks if the projectile vertical coordinate has become
negative to indicate that the object has reached the surface. However,
this can overestimate the horizontal intercept. Add code to do an
interpolation to obtain a more accurate intercept.
Most recent update: Oct. 21, 2005
|