Exercise 1:
Download and execute Incline.java.
This is a simulation of a bead falling along an inclined
wire with no friction. You can set the incline angle and
also the mass of the bead.
- Estimate the distance traveled in 1 second, in 2 seconds, 3
seconds ... etc. That is, sketch out a graph with time on the
x-axis and distance (along incline) along the y-axis.
- Estimate the velocity between successive tick marks along
the incline. That is, what is the velocity between the
first two tick marks, between the second two, ... etc.
- How do these graphs change if you double the mass?
- How do these graphs change if you double the angle?
From these observations (only) what can you conclude about
the relationship between:
- Distance traveled and time?
- Velocity and time?
- Mass and distance traveled?
- Angle and distance traveled?
Let us use a more refined tool that will allow more accurate
measurements:
- Suppose we have a measurement device capable of very
accurate measurements:
=>
You set a "time" and it returns the distance traveled.
- We will use one such "virtual measurement device"
=>
A simulator.
- Here is how we'd use a simulator for the incline problem:
(source file)
public class InclineSimulatorExample {
public static void main (String[] argv)
{
// Make an instance of the simulator.
InclineSimulator sim = new InclineSimulator ();
// Set mass and angle.
sim.mass = 1;
sim.angle = 30;
// We'll measure distance travelled at t=1, t=2, ... and put
// these values into a Function object.
Function dist = new Function ("dist");
for (double t=1; t<=10; t+=1) {
double d = sim.run (t);
dist.add (t, d);
}
// Display result.
dist.show ();
}
}
Exercise 2:
Download InclineSimulatorExample.java,
InclineSimulator.java,
Function.java, and
SimplePlotPanel.java.
Then, compile and execute InclineSimulatorExample.
What do you observe is the relationship between distance and time?
Exercise 3:
Modify the code in InclineSimulatorExample.java
to compute the derivative at t=1, 2 ... etc. For example, to
estimate the derivative at t=2, you would
- Obtain d, the distance traveled in 2 seconds.
- Obtain d', the distance traveled in 2.01 seconds.
- Estimate the derivative at t=2 as (d'-d)/0.01.
What do you conclude from estimating the derivative?
Repeat the derivative estimation using 0.0001 instead of 0.01.
Can you explain what you observe?
Let's next explore the idea of instantaneous velocity:
- In the above exercise, we measured the distance-derivative as:
(d'-d)/0.01
- If d(t) is the function that describes distance in
terms of time, then the derivative at time t is
estimated as (d(t + 0.01) - d(t)) / 0.01.
- But d(t+0.01) - d(t) is the distance traveled in the
time interval 0.01
=>
It's short, to be sure, but a non-zero distance nonetheless.
=>
The velocity in that interval is distance-traveled / time-taken
=>
velocity = (d(t + 0.01) - d(t)) / 0.01.
- We call this the instantaneous velocity at time t.
- If we used 0.001 instead of 0.01, the result
would be "even more instantaneous".
- Another way to describe it is this mouthful: instantaneous rate-of-change of distance
Exercise 4:
Consider the function f(x) = 3x+5. Use 0.1 and
compute the instantaneous rate-of-change at x=1, at x=2,
and x=3. Then use 0.01 and compute the same.
What do you conclude? What can you conclude about the instaneous
rate-of-change of any linear function f(x) = ax+b?
About instantaneous rate-of-change:
- For linear functions, there's a nice pictorial
view of what this means:

- For a nonlinear function, it's a little more
complicated:

Exercise 5:
Consider the function f(x) = 3x2+5.
- Use 0.1 and
compute the instantaneous rate-of-change at x=1, at x=2,
and x=3.
- Then use 0.01 and compute the same.
- Suppose we use some value e as the "change". That is,
compute (f(x+e) - f(x)) / e. Can you work this out
by hand for f(x)=3x2+5 and simplify the expression?
Let's take a closer look at instantaneous velocity
in our incline-simulator:
- The instantaneous velocity is itself a function of time:
=>
For every time t, we define the instantaneous-velocity
as (d(t+0.01) - d(t)) / 0.01.
- Let's give this function a name:
v(t) = (d(t+0.01) - d(t)) / 0.01.
- The simulator has been written to provide instantaneous
velocity whenever you want it:
(source file)
public class InclineVelocityExample {
public static void main (String[] argv)
{
// Make a new instance of the class.
InclineSimulator sim = new InclineSimulator ();
// Set mass and angle.
sim.mass = 1;
sim.angle = 30;
// We'll make a Function object to store "velocity" readings.
Function velocity = new Function ("velocity");
for (double t=1; t<=10; t+=1) {
// Run simulator up to time t.
sim.run (t);
// Get the velocity and put that in our function object.
double v = sim.getV ();
velocity.add (t, v);
}
// Display result.
velocity.show ();
}
}
- Suppose we try to compute the derivative of instantaneous velocity
=>
We want (v(t+0.01) - v(t)) / 0.01
Exercise 6:
Execute the above code and estimate the slope (by hand and by code).
Then modify the code to estimate the derivative of the velocity
function at t=1, t=2, ..., t=10.
Acceleration:
- We will give a shorter name to instantaneous rate-of-change
of velocity
=>
It's called acceleration
- Since there is a value of this acceleration at each moment,
it is really a function
=>
a(t) = acceleration at time t.
Exercise 7:
At this point we might try formulating a general "law"
about motion:
- How would you state the law?
- How is the acceleration (velocity-derivative or instantaneous rate-of-change
of velocity) affected by the mass of the bead? Try different
mass values (1, 2, 3, etc).
- How is acceleration affected by the angle?
Try angles of 10, 20, ..., 80. (You might have to re-size
the window).
- What can we say about a universal law at this time?
Exercise 8:
Puzzle: can you measure 30o without a protractor?
That is, can you create an incline at an angle of
30o with a flat object right now without an
angle-measuring device?
Formulating a Universal Law - More Examples
A simpler experiment:
- Consider dropping a ball from a height.
- Let d(t) = height of ball above ground after
t seconds.
- Once again, suppose we have a simulator that returns
the height after a given time, we could use it as follows:
(source file)
public class BallDropSimulatorExample {
public static void main (String[] argv)
{
BallDropSimulator sim = new BallDropSimulator ();
Function dist = new Function ("distance");
for (double t=1; t<=10; t+=1) {
// Drop from a height of 1000
double d = sim.run (t, 1000);
dist.add (t, d);
}
dist.show ();
}
}
Exercise 9:
Execute the above code. You will also need
BallDropSimulator.java.
- Modify the the code in main to estimate the velocity curve.
- Write code to estimate the slope of the velocity curve.
- Thought exercise: picture yourself in the times of Newton (mid 1600's).
How would you perform an experiment to measure d(t) for
a falling object? What was the clock technology like at that time?
A variation:
- Toss a ball upward with some initial velocity.
- Let d(t) = height of ball after t seconds.
- If we have a simulator, we would use it as follows:
(source file)
public class BallTossSimulatorExample {
public static void main (String[] argv)
{
BallTossSimulator sim = new BallTossSimulator ();
Function dist = new Function ("distance");
for (double t=1; t<=10; t+=1) {
double d = sim.run (t, 50);
dist.add (t, d);
}
dist.show ();
}
}
Exercise 10:
Execute the above code. You will also need
BallTossSimulator.java.
Then, modify the the code in main to estimate
the velocity curve. What can you conclude about your
universal law thus far?
Exercise 11:
Download and execute Projectile.java.
- What is the path followed by the projectile?
- What complication does this create for the universal law?
Going the Other Way - from Acceleration to Distance
Before looking further into our universal law, let us take
a closer look at the relationship between acceleration, velocity,
and distance
=>
Our law somehow accounts for these quantities.
Reconstructing motion from acceleration:
- Suppose we know that acceleration is constant, could
we reconstruct motion (the distance function)?
- This is what we know:
- The derivative of the distance-function d(t) is:
the velocity function v(t).
- The derivative of the velocity-function v(t)
is: the acceleration function a(t).
- What we'd like to do: construct d(t) when
we know (or are given) a(t).
- For example, if a(t)=5 (constant acceleration),
then what is d(t)?
- Let us first write a simple program to reconstruct
v(t) using the following reasoning:
- We know that a(t) = (v(t+s) - v(t)) / s for some
small value s (e.g., s=0.01).
- Then, rearranging gives us v(t+s) = v(t) + s a(t).
- Suppose we know v(0) = 0.
=>
(Turns out, we have to know the initial value.)
- Then, we could compute v(0+s) = v(0) + s * a(0).
- Now that we know v(s)
=>
We can compute v(s+s) = v(s) + s * a(s).
- Then, compute v(3s) = v(2s) + s * a(2s).
- Then, compute v(4s) = v(3s) + s * a(3s).
- ... etc
Exercise 12:
Suppose a(t)=4.9 (acceleration is a constant value
of 4.9), and that initial velocity is zero.
- Draw a graph of a(t) in the range [0,10].
- Use s=0.1 and compute by hand v(0.1), v(0.2), v(0.3),
v(0.4), v(0.5). Show your calculations.
- Explain why the value for v(0.5) makes sense.
- What is the connection between the calculations you did
and the terms "line" and "slope"? What is the equation of
the line in question?
Next, let's write a small program to compute v(t):
- We'll use a(t)=4.9 as an example.
- Here's the program
(source file)
public class IntegrateAccel {
public static void main (String[] argv)
{
// a(t) = 4.9 (constant acceleration).
double a = 4.9;
// Initial velocity.
double v = 0;
// Our small "change" interval
double s = 0.1;
// Start and end time.
double t = 0;
double endTime = 0.5;
while (t < endTime) {
System.out.println (">> t=" + t + " v=" + v);
v = v + s * a;
t = t + s;
}
System.out.println ("Final: t=" + t + " v=" + v);
}
}
- Note:
- The key statement is:
// Update velocity:
v = v + s * a;
- Here, the "new" velocity (at time t+s) is the "old"
velocity (at time t) plus the interval length (s)
times the slope (a).
- A less efficient, but perhaps more understandable way of
writing the same code would be:
while (t < endTime) {
// Print current time and velocity:
System.out.println (">> t=" + t + " v=" + v);
// Compute what the new velocity should be:
double next_v = v + s * a;
// Compute what the new time value should be:
double next_t = t + s;
// Now change both v and t to reflect the new values.
v = next_v;
t = next_t;
}
- We will rewrite the code slightly so that the loop is
in a method by itself:
(source file)
public class IntegrateAccel2 {
static double a;
static double v;
static double s;
static double t;
public static void main (String[] argv)
{
// a(t) = 4.9 (constant acceleration).
a = 4.9;
// Initial velocity.
v = 0;
// Our small "change" interval
s = 0.1;
// Start and end time.
t = 0;
// First example of using the method:
double finalVelocity = computeFinalVelocity (0.5);
System.out.println ("t=" + t + " finalv=" + finalVelocity);
// Second example:
finalVelocity = computeFinalVelocity (0.7);
System.out.println ("t=" + t + " finalv=" + finalVelocity);
}
public static double computeFinalVelocity (double endTime)
{
while (t < endTime) {
// Update velocity:
v = v + s * a;
// Update time:
t = t + s;
}
return v;
}
}
Note:
- We have now pushed the loop into a method that can be called
repeatedly.
- The key variables are now declared global to the class so
that they are accessible from the method.
- Alternatively, we could have written this as:
(source file)
public class IntegrateAccel3 {
public static void main (String[] argv)
{
// First example of using the method:
double finalVelocity = computeFinalVelocity (4.9, 0, 0, 0.5, 0.1);
System.out.println ("t=" + 0.5 + " finalv=" + finalVelocity);
// Second example:
finalVelocity = computeFinalVelocity (4.9, 0, 0, 0.7, 0.1);
System.out.println ("t=" + 0.7 + " finalv=" + finalVelocity);
}
public static double computeFinalVelocity (double a, double initialVelocity, double initialTime, double endTime, double s)
{
double v = initialVelocity;
double t = initialTime;
while (t < endTime) {
// Update velocity:
v = v + s * a;
// Update time:
t = t + s;
}
return v;
}
}
Note:
- All variables are now passed in as parameters.
- The initial values of variables v, t are now set
inside the computeFinalVelocity() method.
Exercise 13:
Which approach above is better and why?
Let's now write some code to produce a complete velocity function:
- In the above examples, we computed v(t) for t=0.5
and t=0.7
=>
These are only two values.
- What we want is the complete v(t) function.
- To do this, we can use a Function object and store
a number of values in our desired range, for example:
(source file)
public class IntegrateAccel4 {
public static void main (String[] argv)
{
// Make the object.
Function velocityCurve = new Function ("velocity");
for (double end=0.1; end<=10; end+=0.1) {
// Compute final velocity at desired x-value:
double finalVelocity = computeFinalVelocity (4.9, 0, 0, end, 0.1);
// Put the (x,y) values into the object.
velocityCurve.add (end, finalVelocity);
}
// Display.
velocityCurve.show ();
}
public static double computeFinalVelocity (double a, double initialVelocity, double initialTime, double endTime, double s)
{
double v = initialVelocity;
double t = initialTime;
while (t < endTime) {
// Update velocity:
v = v + s * a;
// Update time:
t = t + s;
}
return v;
}
}
Exercise 14:
Execute the above code and confirm your earlier hand calculations.
Then, explore the following issues:
- There is something wasteful about the way we are creating
v(t). Can you see what it is? Can the code be
modified to make it more efficient?
- Modify the program to print only v(10) (Remove
the display of the function).
- What is the effect of changing the interval size? Suppose
the interval size is 0.001? Suppose the interval size
is 2.0?
Now that we've computed the velocity function v(t),
we can try to compute the distance function d(t):
- Recall that v(t) is the derivative of d(t).
=>
Use the same approach
- Assume we know v(t) (or have computed it before).
- By the definition of v(t):
v(t) = (d(t+s) - d(t)) / s for some small value s.
- Then, rearranging, we get d(t+s) = d(t) + s v(t).
- Assume we know the initial value d(0).
- Then d(0+s) = d(0) + s v(0).
- After which we compute d(s+s) = d(s) + s v(s).
- After which we compute d(3s) = d(2s) + s v(2s) ... etc.
- Thus, we could write a program for compute d(t) as follows:
(source file)
public class IntegrateVelocity {
public static void main (String[] argv)
{
// Compute velocity function as before.
Function velocityCurve = new Function ("velocity");
for (double end=0.1; end<=10; end+=0.1) {
double finalVelocity = computeFinalVelocity (4.9, 0, 0, end, 0.1);
velocityCurve.add (end, finalVelocity);
}
// Compute distance at t=5:
double finalDistance = computeFinalDistance (velocityCurve, 0, 0, 5, 0.01);
System.out.println ("t=5 d=" + finalDistance);
// Compute distance at t=10:
finalDistance = computeFinalDistance (velocityCurve, 0, 0, 10, 0.01);
System.out.println ("t=10 d=" + finalDistance);
}
public static double computeFinalVelocity (double a, double initialVelocity, double initialTime, double endTime, double s)
{
// ... same as before ...
}
// This is similar to how we computed velocity.
public static double computeFinalDistance (Function velocity, double initialDistance, double initialTime, double endTime, double s)
{
double d = initialDistance;
double t = initialTime;
while (t < endTime) {
// Update distance:
double v = velocity.get (t);
d = d + s * v;
// Update time:
t = t + s;
}
return d;
}
}
Exercise 15:
Execute the above code and confirm the results by comparing
it to the results from the
InclineSimulatorExample.java
example from earlier. How exactly did you confirm the results?
Then, explore the following issues:
- There is something wasteful about the way we are creating
d(t). Can you see what it is? Can the code be
modified to make it more efficient?
- What is the effect of changing the interval size?
Try interval sizes of 0.1 and 1.0.
- Why does interval size matter more in this case?
Can we combine the velocity and distance computations?
- Look at the code that computes distance:
while (t < endTime) {
// Update distance:
double v = velocity.get (t);
d = d + s * v;
// Update time:
t = t + s;
}
- Here, we have already computed the velocity function v(t).
- We simply retrieve stored values each time we need it in the loop.
- Instead, we can compute velocity values on-the-fly because
the loops for velocity and distance are really the same:
(source file)
public class IntegrateVelocity2 {
public static void main (String[] argv)
{
// No need to compute velocity function.
// Compute distance at t=5:
double finalDistance = computeFinalDistance (0, 0, 0, 5, 0.01);
System.out.println ("t=5 d=" + finalDistance);
// Compute distance at t=10:
finalDistance = computeFinalDistance (0, 0, 0, 10, 0.01);
System.out.println ("t=10 d=" + finalDistance);
}
public static double computeFinalDistance (double initialVelocity, double initialDistance, double initialTime, double endTime, double s)
{
// Constant acceleration.
double a = 4.9;
// Set initial values.
double v = initialVelocity;
double d = initialDistance;
double t = initialTime;
while (t < endTime) {
// First compute velocity:
v = v + s * a;
// Then, update distance:
d = d + s * v;
// Update time:
t = t + s;
}
return d;
}
}
- Let's consider one more issue:
- Should we change distance after (as above) or
before changing velocity?
- That is, what if we had written:
(source file)
public class IntegrateVelocity3 {
public static void main (String[] argv)
{
// No need to compute velocity function.
// Compute distance at t=5:
double finalDistance = computeFinalDistance (0, 0, 0, 5, 0.01);
System.out.println ("t=5 d=" + finalDistance);
// Compute distance at t=10:
finalDistance = computeFinalDistance (0, 0, 0, 10, 0.01);
System.out.println ("t=10 d=" + finalDistance);
}
public static double computeFinalDistance (double initialVelocity, double initialDistance, double initialTime, double endTime, double s)
{
// Constant acceleration.
double a = 4.9;
// Set initial values.
double v = initialVelocity;
double d = initialDistance;
double t = initialTime;
while (t < endTime) {
// First update distance:
d = d + s * v;
// Then update velocity:
v = v + s * a;
// Update time:
t = t + s;
}
return d;
}
}
- It turns out that both are slightly different algorithms:
one is better than the other in certain situations
=>
The formal study of this type of question is called
Numerical Analysis.
- The second came first historically and is called the
Euler Algorithm.
- The first method is sometimes called Euler-Cromer Algorithm.
Exercise 16:
What could you do experimentally to determine which of
Euler or Euler-Cromer is better?
Finally, let's recall that we had a simulator for the Incline problem:
- Let's revisit that program:
(source file)
public class InclineSimulator {
// Mass and angle.
public double mass = 1;
public double angle = 30;
// Acceleration, velocity, distance, and time.
double a = 0;
double v = 0;
double d = 0;
double t = 0;
// Each time step.
double delT = 0.001;
// We'll explain "g" later.
double g = 9.8;
public double run (double stopTime)
{
// Acceleration along incline: g*sin(alpha).
double angleRadians = 2*Math.PI*angle / 360.0;
a = g * Math.sin(angleRadians);
// Initialize variables.
v = 0;
d = 0;
t = 0;
while (true) {
// Update time.
t += delT;
// Increase velocity according to (constant) acceleration a.
v = v + delT * a;
// Increase distance according to velocity.
d = d + delT * v;
if (t >= stopTime) {
break;
}
}
// This is the distance moved in time t=stopTime.
return d;
}
public double getV ()
{
return v;
}
public double getA ()
{
return a;
}
public double getX ()
{
double angleRadians = 2*Math.PI*angle / 360.0;
return d * Math.cos (angleRadians);
}
public double getY ()
{
double angleRadians = 2*Math.PI*angle / 360.0;
return d * Math.sin (angleRadians);
}
}
Exercise 17:
Examine InclineSimulator above and answer these questions:
- Is this the Euler or Euler-Cromer Algorithm at work?
- Is the acceleration changing with time?
- The while-loop has a slightly different structure. Any reason
to prefer this approach or the earlier approach?
Coordinates
Let's return to the Projectile.java
example from earlier:
- Recall that the ball moves along a curve.
- Suppose we try to analyze the distance moved along the
curve:
=>
Let d(t) = distance moved along curve.
- Let's ask whether our "universal law" holds
=>
Is velocity linear? Is acceleration constant?
- For this purpose, we will use a simulation of
the projectile, written in ProjectileSimulator.java.
- Thus, to plot the distance travelled (the d(t)
function):
(source file)
public class ProjectileSimulatorExample {
public static void main (String[] argv)
{
// Make a new simulator object.
ProjectileSimulator proSim = new ProjectileSimulator ();
// We want to plot d vs. t
Function dist = new Function ("distance");
for (double t=0.1; t<=2.3; t+=0.1) {
// mass=1, angle=37, initVel=20, s=0.01
double d = proSim.run (1, 37, 20, t, 0.01);
dist.add (t, d);
}
// Display.
dist.show ();
}
}
Exercise 18:
Download ProjectileSimulator.java
and then modify
ProjectileSimulatorExample.java
to compute the velocity function v(t). Use s=0.01 and,
for the derivative, use v(t)=(v(t+0.1) - v(t)) / 0.1.
What can you conclude about the rate of change of velocity?
We will now explore one key insight in the development of physics:
- Consider a bead coming down an incline, as we've seen in our
examples:

- Suppose we arranged light sources so that shadows of the
bead are projected on the x and y-axes.
- The figure above shows the direction in which the shadows
would move
=>
Rightwards for the x-axis shadow, downwards for the y-axis shadow.
- Suppose we observe only the x-axis shadow:
- The shadow is like a moving object.
- It has a distance, velocity and acceleration functions
that we could measure.
- Similarly, we could observe the y-axis shadow as an
independent object and measure its distance, velocity and
acceleration functions.
Exercise 19:
Execute Incline.java and
observe the shadow objects moving. Are you able to say anything
about whether the shadow objects satisfy our "universal law"?
Next, let's use our incline-simulator to obtain a distance
function along the x-axis:
- The simulator allows you to obtain distance moved by the
x-axis shadow at any time.
- Here's how we'd use it:
(source file)
public class InclineSimulatorExample2 {
public static void main (String[] argv)
{
// Make a new instance of the class.
InclineSimulator sim = new InclineSimulator ();
// Set mass and angle.
sim.mass = 1;
sim.angle = 30;
// Measure x(t) = distance moved along x-axis.
Function dist = new Function ("dist");
for (double t=1; t<=10; t+=1) {
sim.run (t);
double x = sim.getX ();
dist.add (t, x);
}
// Display result.
dist.show ();
}
}
Exercise 20:
Download and execute the above code. Then modify to
compute the velocity of the x-axis shadow.
What do you observe?
Let's see what we get for the projectile problem:
- Once again, we'll observe the shadows (x and y) of the ball.
- Suppose we track the x-axis shadow as follows:
(source file)
public class ProjectileSimulatorExample2 {
public static void main (String[] argv)
{
// Make a new simulator object.
ProjectileSimulator proSim = new ProjectileSimulator ();
// We want to plot d vs. t along x-axis.
Function dist = new Function ("distance");
for (double t=0.1; t<=2.3; t+=0.1) {
// mass=1, angle=37, initVel=20, s=0.01
proSim.run (1, 37, 20, t, 0.01);
// After the simulation is run, get the final x-value.
double x = proSim.getX ();
dist.add (t, x);
}
// Display.
dist.show ();
}
}
Exercise 21:
Execute the above program. What do you notice about the distance
function for the x-axis shadow? Can you explain?
Exercise 22:
Modify the above code to compute and display the distance function
for the y-axis shadow. Do the x-axis and y-axis shadows satisfy
our "universal law"?
Reconstructing motion using "laws along x and y":
Exercise 24:
Explain how d(t) is estimated in the above code? That is,
why does
d = d + distance (x,y, nextX, nextY);
work? Why did we need the variables nextX, nextY?
Can we similarly construct an (x,y) version for the incline problem?
- First, let's look at the current version of the
simulator for the incline problem:
(source file)
public class InclineSimulator {
// ... stuff left out (not shown) ...
public double run (double stopTime)
{
// ... initialization not shown ...
while (true) {
// Update time.
t += delT;
// Increase velocity accordingly.
v = v + delT * a;
// Increase distance according to velocity.
d = d + delT * v;
if (t >= stopTime) {
break;
}
}
return d;
}
}
Note:
- This version merely updates v(t) and d(t) as
we would expect.
- Recall: d(t) is distance moved along the incline.
- Keep in mind that a(t) = a is fixed (constant).
=>
When angle = 30o, it turns out that a =
4.9.
(Why this is so will become clear later)
- OK, now let's look an alternative way to write the
incline-simulator:
(source file)
public class InclineSimulatorXY {
// Mass and angle.
public double mass = 1;
public double angle = 30;
// Separate acceleration, velocity and distance for x and y shadows.
double ax = 0, ay = 0;
double vx = 0, vy = 0;
double x = 0, y = 0;
// Time and time-step.
double t = 0;
double delT = 0.001;
// Vertical acceleration.
double g = 9.8;
public double run (double stopTime)
{
// Acceleration along incline: g*sin(alpha).
double angleRadians = 2*Math.PI*angle / 360.0;
double a = g * Math.sin(angleRadians);
// Initialize variables.
vx = 0; vy = 0;
x = 0; y = 0;
t = 0;
// We'll track total distance traveled along incline.
double d = 0;
while (true) {
// Update time.
t += delT;
// Acceleration along x and y.
ax = a * Math.cos (angleRadians);
ay = a * Math.sin (angleRadians);
// Increase velocity according to appropriate acceleration.
vx = vx + delT * ax;
vy = vy - delT * ay;
// Increase distance in each direction according to appropriate velocity.
double nextX = x + delT * vx;
double nextY = y + delT * vy;
// Update total distance traveled.
d = d + Math.sqrt ((nextX-x)*(nextX-x) + (nextY-y)*(nextY-y));
x = nextX;
y = nextY;
if (t >= stopTime) {
break;
}
}
return d;
}
}
Note: observe how the appropriate variables are computed for the x-shadow:
ax = a * Math.cos (angleRadians);
- We know that the acceleration along the incline is
a (from the previous version of the inclinesimulator).
- Our reasoning showed that acceleration along the x-direction
(for the x-shadow) is ax(t) = a(t) cos(angle).
- Once we know ax(t)
=>
we can compute vx(t)
=>
From which we can compute x(t) (distance moved along the x-axis).
Exercise 25:
This clean "separation" into x and y shadows appears mystifying.
Do you believe it works? Download and execute
InclineSimulatorExample3.java
to compare the two simulators.
Print out the horizontal and vertical accelerations.
Some Unfinished Business
What exactly is g?
- We know that a dropping (or even a tossed) ball
experiences a downward "pull"
=>
Informally, we refer to this as gravity.
- Our simulations show that the acceleration is constant
and that the constant is g = 9.8.
- We've used this fact in several simulations:
- In BallDropSimulator and BallTossSimulator:
// Update time.
t += delT;
// Decrease velocity by downward acceleration.
vy = vy - delT * g;
// Increase distance (y) according to velocity (which will reduce height)
y = y + delT * vy;
- In ProjectileSimulator:
// Apply g to vy. Note: vx stays the same.
vy = vy - g * delT;
The question we've avoided so far: what causes this
acceleration? Why is it constant?
Exercise 26:
Are there more unanswered questions regarding gravity?
Unfinished business relating to the incline problem:
- We saw that there is acceleration in the x-direction.
=>
What exactly is causing this acceleration? Who's doing the
"pushing" in that direction?
- Why isn't the vertical acceleration simply g?
Exercise 27:
Do you have answers for the above two questions?
As it turns out they are quite significant.
Other unanswered questions:
- We haven't talked about units. In what units do we get
g=9.8? What about units for velocity?
- We've all heard the term "force" used in connection with
the laws of motion. How does "force" relate to what we've
discussed?
Problem Solving
Let's start by asking a few questions about the Ball-Drop problem:
- What is the final velocity when the ball hits the ground after
being dropped from a height of 1000?
- At what height should one drop the ball to get a final
velocity of approximately 200?
- At what time and height is the velocity half the final
velocity (when dropped from a height of 1000)?
Now let's tackle these questions:
- First, we'll start by modifying the simulator to return
the final velocity instead of time:
(source file)
public class BallDropSimulator2 {
double vy;
double t;
public double run (double height)
{
// Initialize variables.
double a = 9.8;
// We'll use "y" for distance (falling along y-axis) and "vy" for velocity.
double y = height;
vy = 0;
t = 0;
double delT = 0.001;
while (true) {
// Update time.
t += delT;
// Decrease velocity by downward acceleration.
vy = vy - delT * a;
// Increase distance (y) according to velocity (which will reduce height)
y = y + delT * vy;
if (y <= 0) { // Stop if it's hit the ground.
break;
}
}
return y;
}
public double getV ()
{
return vy;
}
public double getT ()
{
return t;
}
}
Note:
- We've created methods to return the final velocity and
the time at which the ball hits the ground.
- To do this, we've had to make these variables global.
- We've increased the accuracy slightly (from 0.01 to 0.001).
- Now let's write a separate program to use the simulator
and answer the first question:
(source
file)
public class BallDropSimulatorExercise {
public static void main (String[] argv)
{
BallDropSimulator2 sim = new BallDropSimulator2 ();
// Drop the ball from a height of 1000.
sim.run (1000);
// Obtain final velocity and time taken for the fall.
double finalVelocity = sim.getV ();
double timeTaken = sim.getT ();
System.out.println ("finalVelocity=" + finalVelocity + " time=" + timeTaken);
}
}
- To answer the second question, we will try different height
values systematically:
(source
file)
public class BallDropSimulatorExercise2 {
public static void main (String[] argv)
{
BallDropSimulator2 sim = new BallDropSimulator2 ();
// Drop the ball from a height of 1000.
double height = 1000;
sim.run (height);
double finalVelocity = sim.getV ();
while ( Math.abs (finalVelocity + 200) > 1 ) {
// Try different heights systematically.
height += 1;
sim.run (height);
finalVelocity = sim.getV ();
}
System.out.println ("Height required: " + height);
}
}
Note:
- Because velocities are negative (going down), the difference
the velocity and 200 has a + sign.
Exercise 28:
How many times is the loop iterated?
Can you think of a more efficient algorithm for the same problem?
Exercise 29:
Modify the code to answer the third question:
At what time and height is the velocity half the final
velocity (when dropped from a height of 1000)?
Next, let's look at the ball-tossing problem (toss a ball up
with some initial velocity) and ask these questions:
- What is the maximum height reached by the ball?
- What initial velocity is needed to reach a height of 1000?
- Suppose the ball is launched with an initial velocity
of 50, and suppose we observe the velocity at a height of 100.
Is the velocity the same going up as it is going down at this height?
Let's answer some of these questions now:
- First, we'll modify the simulator to return the velocity:
(source file)
public class BallTossSimulator2 {
// We made this a global variable ...
double vy;
public double run (double stopTime, double initVelocity)
{
// Initialize variables.
double a = 9.8;
vy = initVelocity;
double y = 0;
double t = 0;
double delT = 0.01;
while (true) {
// Update time.
t += delT;
// Increase velocity accordingly.
vy = vy - delT * a;
// Increase distance according to velocity.
y = y + delT * vy;
if ((t >= stopTime) || (y <= 0)) {
break;
}
}
return y;
}
public double getV ()
{
// ... so that it's accessible here.
return vy;
}
}
- Notice the input parameters to the run() method:
- One parameter is the length of the simulation (which might
stop before the ball hits the ground).
- The other is the launch velocity.
- How do we know how much extra time to give (to allow for
the ball to come down and hit the ground)?
=>
We don't - so let's find out by writing a simple program:
(source file)
public class BallTossExercise {
public static void main (String[] argv)
{
// Make an instance of our new simulator.
BallTossSimulator2 sim = new BallTossSimulator2 ();
// We'll start by trying 1 second.
double stopTime = 1;
double y = sim.run (stopTime, 50);
// As long as we haven't hit ground, keep trying higher values of t.
while (y > 0) {
stopTime += 10;
y = sim.run (stopTime, 50);
}
// This should be sufficient:
System.out.println ("stopTime=" + stopTime + " y=" + y);
}
}
(Turns out: 12 seconds is enough).
- OK, next let's find the maximum height reached:
- How do we do this?
- Here's one idea: we try different stop-time's until,
in two successive attempts, the height decreases.
Here's the program:
(source file)
public class BallTossExercise2 {
public static void main (String[] argv)
{
// Make an instance of our new simulator.
BallTossSimulator2 sim = new BallTossSimulator2 ();
// Find the height reached at t=1 and t=2
double stopTime = 1;
double prevY = sim.run (stopTime, 50);
stopTime = 2;
double nextY = sim.run (stopTime, 50);
while (nextY > prevY) {
// As long as y(t+1) > y(t), repeat.
prevY = sim.run (stopTime, 50);
stopTime = stopTime + 1;
nextY = sim.run (stopTime, 50);
}
// Now we're sure that y(t+1) < y(t)
System.out.println ("stopTime=" + stopTime + " prevY=" + prevY + " nextY=" + nextY);
}
}
- We can add to this code to find the velocity needed to reach
a height of 1000:
(source file)
public class BallTossExercise3 {
public static void main (String[] argv)
{
for (double initVelocity=50; initVelocity<500; initVelocity+=50) {
// Try this initial velocity:
double heightReached = getMaxHeight (initVelocity);
if (heightReached > 1000) {
// If we've exceeded 1000, then stop.
System.out.println ("initV=" + initVelocity + " height=" + heightReached);
break;
}
}
}
static double getMaxHeight (double initVelocity)
{
// Make an instance of the simulator.
BallTossSimulator2 sim = new BallTossSimulator2 ();
// Find the height reached at t=1 and t=2
double stopTime = 1;
double prevY = sim.run (stopTime, initVelocity);
stopTime = 2;
double nextY = sim.run (stopTime, initVelocity);
while (nextY > prevY) {
// As long as y(t+1) > y(t), repeat.
prevY = sim.run (stopTime, initVelocity);
stopTime = stopTime + 1;
nextY = sim.run (stopTime, initVelocity);
}
// Now we're sure that y(t+1) < y(t)
System.out.println ("initV=" + initVelocity + " stopTime=" + stopTime + " prevY=" + prevY + " nextY=" + nextY);
return prevY;
}
}
Note:
- We have made a method out of the sub-problem of "finding
the maximum height for a given initial velocity".
- This sub-problem is then called repeatedly in steps of 50.
Exercise 30:
How would you get a more accurate estimate of the initial
velocity needed to reach 1000?
Next we will address the third question: is
the velocity the same going up and down
at a given height?
- We will first modify the simulator as follows:
- We will stop when a given "target height" is reached.
- We will decide whether this height has been reached
before or after the maximum height has been reached.
- The input parameters now accept the target height, and
whether or not one should reach this target before or after the
maximum:
(source file)
public class BallTossSimulator3 {
double vy;
public double run (double stopTime, double initVelocity, double targetHeight, boolean beforeMaxHeight)
{
// Initialize variables.
double a = 9.8;
vy = initVelocity;
double y = 0;
double t = 0;
double delT = 0.01;
boolean maxReached = false;
while (true) {
// Update time.
t += delT;
// Increase velocity accordingly.
vy = vy - delT * a;
// Increase distance according to velocity.
double nextY = y + delT * vy;
double prevY = y;
y = nextY;
if (y < prevY) {
maxReached = true;
}
if (beforeMaxHeight) {
if (y > targetHeight) {
// Done.
break;
}
}
else if (maxReached) {
if (y < targetHeight) {
// Done.
break;
}
}
if ((t >= stopTime) || (y <= 0)) {
break;
}
}
return y;
}
public double getV ()
{
return vy;
}
}
Note:
- We use the same idea (observing successive y values) to see
if the maximum has been reached.
- We wait for "y > target" in the "before" case, and
for "y < target" in the "after" case.
- It's easy now to check the "before" and "after" velocities:
(source file)
public class BallTossExercise4 {
public static void main (String[] argv)
{
// Make an instance of modified simulator.
BallTossSimulator3 sim = new BallTossSimulator3 ();
sim.run (1000, 50, 100, true);
double beforeV = sim.getV ();
sim.run (1000, 50, 100, false);
double afterV = sim.getV ();
System.out.println ("before: " + beforeV + " after: " + afterV);
}
}
Exercise 31:
So, is it true that the two velocities are the same?
Is there an intuition for why or why not?
Consider these questions about the projectile problem:
- For a fixed velocity of 50, which angle results in the farthest
horizontal distance traveled?
=>
This is an age-old ballistics problem
- Suppose we want the projectile to hit a target at a distance
of 200 from the launch point. Find two combinations of angle and
initial velocity to achieve this goal. Of the two, which
one has a smaller time-of-flight?
- We'll begin by re-writing the simulator slightly:
(source file)
public class ProjectileSimulator2 {
double x=0, y=0; // Track (x,y)
double vx, vy; // Velocity components
public double run (double angle, double initialVelocity)
{
// Initialize values.
double delT = 0.001; // Interval of time.
double t = 0; // Current time.
double g = 9.8; // 9.8 N
double theta = Math.toRadians (angle); // Convert degrees to radians.
x = 0;
y = 0;
// Initial vx = component of initialVelocity in x-direction.
vx = initialVelocity * Math.cos (theta);
// Initial vy = component of initialVelocity in y-direction.
vy = initialVelocity * Math.sin (theta);
while (y >= 0) {
// Apply g to vy. Note: vx stays the same.
vy = vy - g * delT;
// Apply vx to x.
x = x + vx * delT;
// Apply vy to y.
y = y + vy * delT;
t = t + delT;
}
return t;
}
public double getX ()
{
return x;
}
}
Note:
- The input parameters are: launch angle and velocity.
- The simulator returns the time taken for the flight.
- There is a method getX() that we can
call to obtain the horizontal distance traveled.
- Next, let's use the initial velocity of 50, and try
different angles:
(source file)
public class ProjectileExercise {
public static void main (String[] argv)
{
// Make an instance of our new simulator.
ProjectileSimulator2 sim = new ProjectileSimulator2 ();
// Launch velocity is 50.
double initV = 50;
// Try angles in the range [10,80]
for (double angle=10; angle<=80; angle+=1) {
sim.run (angle, initV);
double x = sim.getX ();
System.out.println ("angle=" + angle + " x=" + x);
}
}
}
- A slightly more elegant approach would be to record the
the best result in the loop:
(source file)
public class ProjectileExercise2 {
public static void main (String[] argv)
{
// Make an instance of our new simulator.
ProjectileSimulator2 sim = new ProjectileSimulator2 ();
// Launch velocity is 50.
double initV = 50;
// Try angles in the range [10,80]
double bestAngle = 10;
double bestX = 0;
for (double angle=10; angle<=80; angle+=1) {
sim.run (angle, initV);
double x = sim.getX ();
if (x > bestX) {
bestAngle = angle;
bestX = x;
}
}
System.out.println ("Best angle: " + bestAngle);
}
}
Exercise 32:
What is the best angle? Run the program and find out.
Does it make intuitive sense?
Exercise 33:
Write code to solve the second problem: find two
angle/velocity combinations to reach a target
at a distance of 200. What is the time-of-flight
for each?
Problem Solving II
Consider the following problem:
Exercise 33:
Is it obvious that the route within each region must be
a straight line?
Let us draw the configuration on the x-y plane:
- We'll put A on the y-axis, and B on the x-axis:

- Let P be a candidate crossing point.
Exercise 34:
Compute by hand the time taken to go from A to P, and
the time taken to go from P to B in terms of
a, b, v1, v2, x, y.
Then download and modify
TwoVelocityProblem.java
and implement your formulas as code. Compare the program's
results with your hand-worked results.
Exercise 35:
Suppose v1 is (much) smaller than
v2. Which of the three routes shown
below is likely to be best?

Next, we will start to solve the optimization problem:
- First, some notation:

- d1 = distance traveled in first phase.
- d2 = distance traveled in second phase.
- (a-y) = vertical distance in first phase
- y = vertical distance in second phase
- Since the border is fixed, x is fixed.
=>
We only need to find the best possible y for the
point P = (x,y).
Exercise 36:
Then download and modify
TwoVelocityProblem2.java
to try different values of y in a loop.
Next, let's see if we can discover the "law" at work:
- We will vary the ratio v2 / v1.
- For each possible ratio, we want to identify the
best y value.
- We would like to discover the relationship between
the ratio v2 / v1 ... and something
related to the problem parameters.
Exercise 37:
Then download and modify
TwoVelocityProblem3.java
to try different values of y in a loop, and also
compare with the distances d1, d2, (a-y),
y.
Notice that we are using different ratios
v2 / v1.
- Is there a relationship between v2/v1
and d2/d1?
- Between v2/v1
and (a-y)/y?
Now we will consider the case, when velocity is NOT constant:
- Consider a bead sliding down a wire.

- Suppose that we can use two straight-line segments.
- Suppose also that the "kink" doesn't slow down the bead.
Is the fastest way down the straight line (in black)? Or is
it faster to use two segments of different slopes?
- Without loss of generality, we will assume
the starting point is (x1,y1)
and that the ending point is (x3,y3).
- We are free to choose the "turning" point
(x2,y2)
Exercise 38:
Before playing with a simulation, what does your intuition tell you?
We'll start by re-writing our incline simulator to simulate
a single segment:
- A segment will be defined by the end points
(x1,y1) (left and above),
and (x2,y2) (right and below).
- Here's the code:
(source file)
public class InclineSegmentSimulator {
// Separate acceleration, velocity and distance for x and y shadows.
double ax = 0, ay = 0;
double vx = 0, vy = 0;
double x = 0, y = 0;
// Time and time-step.
double t = 0;
double delT = 0.001;
// Vertical acceleration.
double g = 9.8;
public double run (double x1, double y1, double x2, double y2, double initvx, double initvy)
{
// Acceleration along incline: g*sin(alpha).
double hyp = distance (x1,y1, x2,y2);
double xDiff = Math.abs (x1-x2);
double yDiff = Math.abs (y1-y2);
double sineOfAngle = xDiff / hyp;
double cosineOfAngle = yDiff / hyp;
// Acceleration along incline.
double a = g * sineOfAngle;
// Acceleration along x and y.
ax = a * cosineOfAngle;
ay = a * sineOfAngle;
// Initialize velocity components.
vx = initvx; vy = initvy;
// Distance components.
x = x1; y = y1;
t = 0;
while (true) {
// Update time.
t += delT;
// Increase velocity according to appropriate acceleration.
vx = vx + delT * ax;
vy = vy - delT * ay;
// Increase distance in each direction according to appropriate velocity.
x = x + delT * vx;
y = y + delT * vy;
if ((x > x2) && (y < y2)) {
// NOTE: this assumes that (x2,y2) is to the right and below.
break;
}
}
return t;
}
double distance (double x1, double y1, double x2, double y2)
{
return Math.sqrt ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
public double getVx ()
{
return vx;
}
public double getVy ()
{
return vy;
}
}
Note:
- Compare the calculation of the angle's sine/cosine with your
hand computations.
- Notice that the initial velocity is assumed to be given as input.
- The simulator is written to return the total time taken down
the incline.
- Let's use this simulator as follows for a two-segment problem:
(source file)
public class TwoSegmentIncline {
public static void main (String[] argv)
{
// Make an instance of the simulator.
InclineSegmentSimulator sim = new InclineSegmentSimulator ();
// Run the straight incline as one segment.
double t = sim.run (0, 10, 10, 0, 0, 0);
System.out.println ("Straight solution: " + t);
// Now, a potential two segment solution. First segment:
double t1 = sim.run (0, 10, 5, 5, 0, 0);
// Get time taken for the second segment:
double t2 = ...
// Comparison:
System.out.println ("Twisted solution: " + (t1+t2));
}
}
Exercise 39:
Download TwoSegmentIncline.java
and
InclineSegmentSimulator.java
Fill in the missing code above in InclineSegmentSimulator.
What reasoning did you use in the missing code? What can you
say about the underlying principle?
Next, let's see if we can find a faster two-segment solution:
- Suppose we fix x2=5 above (the middle of the incline).
=>
We will try to find the best y2.
- One simple way is to try various values:
(source file)
public class TwoSegmentIncline2 {
public static void main (String[] argv)
{
// Make an instance of the simulator.
InclineSegmentSimulator sim = new InclineSegmentSimulator ();
// Run the straight incline as one segment.
double t = sim.run (0, 10, 10, 0, 0, 0);
System.out.println ("Straight solution: " + t);
double x2 = 5;
for (double y2=1; y2<=9; y2+=1) {
// Now, a potential two segment solution. First segment:
double t1 = sim.run (0, 10, x2, y2, 0, 0);
double t2 = ...
// Comparison:
System.out.println ("Twisted solution for y2=" + y2 + ": " + (t1+t2));
}
}
// ...
}
Exercise 40:
Fill in the missing code above.