So here's a formula for bouncing in a rectangular.

Let's assume the following, and only worry about the x coordinate:

- left side is x = 0
- right side is xr
- x velocity is vx
- t is the time
- x0 is the initial position

So, if we were not in a box, the x position at time t would be:

- x(t) = x0 + t*vx

If we just divided by xr and took the remainder, ie, mod by xr, we would restrict location of the ball to the box:

- F(t) = mod (x(t), xr) = mod (x0 + t*vx, xr)

But this would not be bouncing off the right wall, just wrapping the path back to the left edge with the same slope.

What we really want is to reverse the motion from the right side when the ball goes off the right edge.

BUT, if we do that, then we really want to reverse the direction the second time we meet a right boundary - which is the same as hitting the left wall (x=0) from the right. The result of this is going in the same direction as the original path.

A clever trick is to think of the box as TWICE the width of the original box, with the left side following the original path, but the right side folded over, showing the reverse path.

So, here's the final math:

- G(t) = mod (x(t), 2*xr)

H(t) gives the final x coordinate.

This is not very hard to program in Excel, particularly if you use more than one column for the intermediate functions of t.

For those with a more algorithmic bent, this is an excellent example where thinking about a bigger problem (larger t) actually gives a simpler insight than simply thinking about what happens when t goes just over the boundary.

In this case, H(t) is the same as H after the ball hits the left and right side.

- H(t) = H(t + 2*xr/vx)

Perhaps it helps to think about what happens with x(t) if the top boundary is removed and we think of a ball bouncing in an infinite column.

And y works the same way, but the y folds are not the same size as the x folds since vx is not the same as vy.

PS - things are only a little more complicated if vx < 0.

ND.

// File: BoxND.java

// Date: Apr 30, 2016

// Author: Nicholas Duchon

// Purpose: step a line around a box

// showing reflections

import java.util.Scanner;

double x, y, vx, vy, bx, by;

Scanner sn = new Scanner (System.in);

System.out.print ("Enter box size, initial x, y and vx and vy: ");

bx = sn.nextDouble ();

by = sn.nextDouble ();

x = sn.nextDouble ();

y = sn.nextDouble ();

vx = sn.nextDouble ();

vy = sn.nextDouble ();

sn.nextLine(); // eat end of line from this input

while (menu());

System.out.println (".. Bye");

System.out.print ("enter stop time and step as doubles or q to quit: ");

String line = sn.nextLine();

if (line.trim().startsWith ("q")) return false;

double t = 0, step = 1.0;

Scanner st = new Scanner (line);

try {

t = st.nextDouble ();

step = st.nextDouble ();

}

catch (NumberFormatException e) {return true;}

int count = 0;

for (double tn = 0; tn < t; tn+= step, count++) {

System.out.printf ("%7.1f %7.1f %7.1f\n", tn, getX (tn), getY (tn));

if ((count % 5) == 4) System.out.println ();

} // end for

// System.out.printf ("f(%5.1f) = (%4.1f, %4.1f)\n", tn, getX (tn), getY (tn));

return true;

double xn0 = x / bx;

double vnx = vx / bx;

double xnt = xn0 + vnx * t;

xnt = xnt % 2;

if (xnt < 0) xnt += 2;

if (xnt > 1) xnt = 2 - xnt;

return xnt * bx;

double yn0 = y / by;

double vny = vy / by;

double ynt = yn0 + vny * t;

ynt = ynt % 2;

if (ynt < 0) ynt += 2;

if (ynt > 1) ynt = 2 - ynt;

return ynt * by;

BoxND b = new BoxND ();

(end)

Oct 15, 2016