Sie sind auf Seite 1von 15

Computer

Simulations of Wave Phenomena


Professional Development Project
SAR High School
2013-2014

Martin Rosenberg

Abstract

This paper describes how the Processing programming language may be used to
simulate a number of wave phenomena. Pulses and waves in a taut rope are
modeled mathematically and computationally. The models are used to simulate
wave motion and wave interference. Particular attention is paid to the simulation of
beats and standing waves. Actual Processing code is interspersed throughout the
text and suggestions are made for further study.

Introduction

Wave phenomena are ubiquitous in nature, ranging from ripples in a puddle during
a rainstorm to the delicate harmonies one enjoys when listening to classical music.
The world around us is permeated by waves. The sounds we hear and the sights we
see come to us initially as wave phenomena and as such are a major topic covered in
introductory physics courses. Modern theories of particle physics (quantum field
theory) actually conceive of everything in the universe, including matter, as a wave.

Once a student moves beyond some basic ideas the study of waves becomes quite
abstract and mathematical. Computer simulations of various wave phenomena are a
time honored solution to the challenge of helping students visualize and understand
the physics that underlies the phenomena they are studying. Most simulations are
presented to the student as black boxes to watch and enjoy. The author has had
the opinion for many years that students learn by doing and that modern computers
and modern programming languages provide an ideal platform for students to learn
both programming skills and physics at the same time. The physicist Richard
Feynman has been quoted as stating What I cannot create I do not understand.
The exercises described below allow students to create wave phenomena in a
virtual world and, hopefully, through the act of creation will come understanding.

The outline of this paper is as follows. I first introduce Processinga programming
language developed at the MIT Media Labs and provided free of charge to anyone
with access to the Internet. The next section discusses the idea of a pulsea single
disturbance that propagates through a mediumand contrasts a pulse with a wave.
This section includes a mathematical description of a pulse and some Processing
programs that simulate a pulse in a rope moving from either left-to-right or right-to-
left, together with options for the pulse to peak upwards or downwards. The next
section discusses traveling wavesperiodic sets of pulses that propagate through a
mediumtogether with, again, both a mathematical description and simulations

based on the Processing programming language. The final section discusses the
wave phenomenon known as interference and includes simulations of the
interference of pulses and traveling waves. Particular attention is paid to the
simulation of standing waves and beats, two classic examples of wave interference.

Processing and Computer Science

Processing is a simple programming language built on top of the Java programming
language. It was conceived of and developed by Casey Reas and Ben Fry of MIT.
Processing simplifies the drawing of geometric shapes on the computer screen and
animating the shapes to provide a simulation of motion. The Processing language
was born as an idea in 2001 and matured through alpha and beta stages from 2002
through 2008. The latest version of the language (2.2.1) is used by thousands of
individual worldwide. The reader is directed to the web site (www.processing.org)
to find details for downloading the software.

The code sample below illustrates how a circle may be drawn initially on the left
side of a window and moved (albeit slowly) towards the right side until it
disappears.

float speed = 0.5;
int radius = 40;
float x = -radius;
void setup()
{
size(1200, 800);
}
void draw()
{
background(0);
x += speed;
ellipse(x, 400, radius, radius);
}


By changing the value of the variable x from 0.5 to 5.0 and running the new
version of the program a student will notice the white circle move at a higher speed
from left to right. By way of explanation the items speed, radius and x are
examples of variables, float and int are example of data types (a float is a
decimal number such as 3.14 while an int is a whole number such as 1, 2 or 3). The
equal sign (=) represents an assignment operator and thus the first line of the
programs declares a variable named speed whose data type is float and assigns
to it the value of 0.5. Every Processing program also contains the so-called
methods setup() and draw(). The setup() method is invoked only once when
the program is started while the draw() method is invoked over and over again as
the program runs. As a default Processing invokes the draw() method sixty times
every second. The ellipse() method draws a circle on the screen. The radius of
the circle is 40 pixels, its y-coordinate is fixed at 400 while its x-coordinate
starts at 0 and increases by 0.5 each time. Since the screen is redrawn sixty

times each second the net result is the perception of the circle moving from left to
right.

Fleshing out the remaining details the line background(0) draws a black
background (the circle is white by default), the line size(1200, 800) creates a
window for drawing that is 1200 pixels wide and 800 pixels deep, the coordinate
system pegs the origin (x = 0 and y = 0) to the upper-left corner of the window with
x-values increasing to the right and y-values increasing in the downward direction.
The reader should note that the y-coordinate increases differently from what one
typically learns of coordinate geometry in a math class. The line x += speed
instructs the program to replace the current value of the variable x with a new value
obtained by adding the value of the variable speed to the current value of x and
reassigning this new value to the variable x. The new value of x is then passed to the
ellipse() method and the circle is re-drawn at a new location.

Pulses

A pulse is defined as a disturbance that travels through a material. A classic example
is dipping a stick once (only once) into a still pond. The stick produces a disturbance
in the water, a ripple, that then propagates outward from where the stick was
dipped into the pond. The ripple is circular and the speed with which the radius of
the circle increases is related to the depth of the pond. Ripples in a pond are two-
dimensional in the sense that the circle moves in the two-dimensional surface of the
pond. It is simpler to model a one-dimensional pulse which may be created by
disturbing one end of a taut rope. The disturbance travels through the rope with a
speed determined by the tension in the rope and its linear mass density. In the two-
dimensional case the medium is the water. In the one-dimensional case the medium
is the rope. Regardless of the dimension and the medium, all pulses may be
described with the same mathematical model. We limit ourselves here to the one-
dimensional case for clarity of exposition.

To model a pulse in one-dimension we envision the medium as consisting of an
array of circles arranged to be touching along a horizontal line. We denote by xi the
x-coordinate of the ith circle. The pulse itself is centered about a specific value of x
denoted as x0. The value of x0 is represents the location of the pulse and, since the
pulse is moving, it is a function of time. The value of x0 is related to the speed of the
pulse, v, and the time elapsed since the pulse was generated, t, by the equation

x0 = vt

The ith circle has a y-coordinate given by

yi = Aexp(-(xi-x0)2/d2) = Aexp(-(xi-vt)2/d2)

where A represents the amplitude (height) of the pulse, xi represents the x-


coordinate of the ith circle, v represents the speed of the pulse, t represents the time
elapsed since the pulse was created, d2 represents a parameter that determines the
width of the pulse, and exp represents the exponential function. We note that the
exponential function has the property that exp(0) = 1 so that the when xi = vt the ith
circle will have a maximum height of A.

A complete program written in the Processing language that animates a pulse
moving in a medium from left to right is given below. The program is explained via
comments inserted directly into the code.

float t= 0.0;
// a variable representing elapsed time
float dt = 1.0;
int numCircles = 150;
boolean bPause = false;
float amplitude = 175.0;
float vel = +16.0;
float xi = 0;
float dd = 100;
int xSpacing = 8;
float[] yValues;

//
//
//
//
//
//
//
//
//
//
//

the increment by which t changes after each loop


the number of circles used to model the medium
a flag to pause and resume the animation
the maximum height of the pulse
the velocity of the pulse
positive for left to right motion
negative for right to left motion
x-coordinate of first circle, 0 for left to right
parameter to control width of pulse
pixels between the centers of adjacent circles
an array to store the y-coordinate of each circle

void setup()
{
size(1200, 800);
yValues = new float[numCircles];
}
void draw()
{
if ( !bPause )
{
background(0);
calcPacket(t);
renderPacket();
t += dt;
}
}
void keyPressed()
{
if ( key == 'p' )
bPause = true;
else
bPause = false;
}

// the dimensions of the display window


// set up the array

// if we are not paused


//
//
//
//

make background of window black


determine yi for each xi as a function of time
draw all the circles
increment the time by dt and loop again

// press p to pause the animation


// press any key other than p to resume animation

void calcPacket(float t)
{
// for every x value and for the t passed as a parameter,
// calculate a y value
// from the equation yi = Aexp(-(xi-vt)2)
float x = 0.0;
float dx = 8;
for (int i = 0; i < yValues.length; i++)
{
float xf = xi + vel*t;
yValues[i] = -amplitude*exp(-(x-xf)*(x-xf)/(dd*dd));
x += dx;
}
}
void renderPacket()
{
// draw the pulse with a circle at each location
for (int i = 0; i < yValues.length; i++)
{
fill(255, 0, 0);
// set up to draw a red circle
ellipseMode(CENTER);
ellipse(i * xSpacing, width / 2 + yValues[i] - 200, 16, 16);
}
}


The interested reader may simply type this program into Processing and run it to
see the animation in action. Some modifications will be of interest later in this
paper. The above code simulates a pulse peaked in the upward direction and
travelling from left to right. To create a pulse peaked in the downward direction
change the amplitude to a negative value by replacing the line
float amplitude = 175.0; // the maximum height of the pulse

with

float amplitude = -175.0; // the maximum depth of the pulse


To create a pulse (regardless of its orientation) moving from right to left change the
two lines

float vel = +16.0;
float xi = 0;


to

float vel = -16.0;
float xi = 1200;


The interested reader may also vary the numerical value of the variable vel to
make the pulse move faster or slower.


Traveling Waves

The term traveling wave refers to a periodic set of pulses that propagate through a
medium. Traveling waves may be described mathematically by either a sine
function or a cosine function. Choosing the former we again use a set of circles to
model the particles in a taut rope and let xi represents the x-coordinate of the ith
circle and yi represents the y-coordinate of the ith circle. We may then state that

yi = Asin(2xi/ 2t/T)

Where A represents the amplitude of the wave (a measure of its energy content),
represents the wavelength of the wave (the crest-to-crest or trough-to-trough
distance) and T represents the period of the wave (the time for one complete cycle).
From the equation it is clear that the wave form is a function of both x and t. If one
keeps the time (t) constant the equation describes a freeze-framed sine curve. If one
focuses on a single value of xi and looks at the corresponding value of yi as a function
of time we find oscillatory (up and down) motion. A complete program written in
the Processing language that animates a traveling wave in a medium moving from
left to right is given below. The program is explained via comments inserted directly
into the code.

float tt = 0.0;
// a variable representing elapsed time
float dtt = 1.0; // the increment by which t changes after each loop
int numParticles = 150; // the number of circles used to model the medium
boolean bPause = false; // a flag to pause and resume the animation
float amplitude = 175.0; // the maximum height of the traveling wave
float speed = 5; // the speed of the traveling wave
int xspacing = 8; // pixels between centers of adjacent circles
float period = 70; // the period of the traveling wave
float wavelength = speed * period; // the wavelength of the traveling wave
float k = 2.0*PI/wavelength; // k and w are variables used to simplify the
float w = 2.0*PI/period;
// mathematical form of the wave below
float[] yvalues; // an array to store the y-coordinate of each circle
void setup()
{
size(1200, 800); // the dimensions of the display window
yvalues = new float[numParticles]; // set up the array
}
void draw()
{
if ( !bPause ) // if we are not paused
{
background(0); // make the background window black
calcWave(tt);
// determine yi for each xi as a function of time
renderWave();
// draw all the circles
tt += dtt;
// increment the time and loop again
}
}

void keyPressed()
// press p to pause the animation
{
// press any other key to resume the animation
if ( key == 'p' )
bPause = true;
else
bPause = false;
}
void calcWave(float t)
{
// for every x value and for the t passed as a parameter,
// calculate a y value
// from the equation y(x,t) = A*sin(kx-wt)
float x = 0.0;
float dx = xspacing;
for (int i = 0; i < yvalues.length; i++)
{
yvalues[i] = amplitude * sin(k*x - w*t) - 200; // change minus to plus for
x+=dx;
// the wave to move to the
// left, the -200 shifts the
// display up
}
}
void renderWave() // draw the traveling wave with a circle at each location
{
for (int i = 0; i < yvalues.length; i++)
{
stroke(255,0,0);
line(400, 0, 400, 1000); // draw red horizontal and vertical guide lines
line(0,400,1200,400);
noStroke();
fill(255,50);
ellipseMode(CENTER);
if ( i == 50 )
// draw 50th circle in green, follow motion up and down
fill(0, 255, 0);
ellipse(i * xspacing, width / 2 + yvalues[i], 16, 16);
}
}


Interference

The wave phenomena typically discussed in an introductory physics course are
reflection, refraction, diffraction, interference, polarization and dispersion. It may be
argued that among these topics, interference is by far and away the most important
and far reaching in terms of its impact on the rest of physics. Interference refers to
what happens when two or more waves occupy the same place at the same time.
When the crest of one wave and the crest of another wave (or the troughs of both
waves) occupy the same place at the same time the result is constructive
interference and the amplitude of the resulting wave is doubled. When the crest of
one wave and the trough of another wave occupy the same place at the same time
the result is destructive interference and the amplitude of the resulting wave is zero.
Constructive interference of sound waves manifests itself as very loud sound while
destructive interference of sound waves manifests itself as silence. Constructive
interference of light waves manifests itself as very bright light while destructive
interference of light waves manifests itself as darkness. In particular, it is the fact

that light is capable of forming an interference pattern that leads to the statement
that light is an electromagnetic wave. Modern physics has shown that light also has
particle-like properties and physicists describe our current understanding of light
with the phrase wave-particle duality. Using the tools previously developed it is
relatively easy to simulate the constructive and destructive interference of both
pulses and traveling waves in a taut rope.

To see constructive interference of pulses one starts with two pulses in the same
rope, both oriented in the same direction (either up or down), with one pulse
traveling from left-to-right and the other pulse traveling from right-to-left. By
pausing the simulation close to the instant when the two peaks occupy the same
place at the same time the doubling of the amplitude is clearly visible.

The following program is modeled after the earlier program that described a single
pulse.
float tt = 0.0;
// time
float dtt = 1.0; // time increment
int numParticles = 150;
boolean bPause = false;
float amplitude_1 = 175.0;
float amplitude_2 = 175.0;
// motion to the right
float vel_1 = 1;
float xi_1 = 0;
// motion to the left
float vel_2 = -1;
float xi_2 = 1200;
float xf_1 = 0;
float aa_1 = 100;
float xf_2 = 0;
float aa_2 = 100;
int xspacing = 8;
float[] yvalues_1;
float[] yvalues_2;
// initialization
void setup()
{
size(1200, 800);
frameRate(30);
colorMode(RGB,255,255,255,100);
smooth();
yvalues_1 = new float[numParticles];
yvalues_2 = new float[numParticles];
}

void draw()
{
if ( !bPause )
{
background(0);
calcPackets(tt);
renderPackets();
tt += dtt;
}
}
void keyPressed()
{
if ( key == 'p' )
bPause = true;
else
bPause = false;
}
void calcPackets(float t)
{
// for every x value and for the "t" passed as a parameter,
// calculate a y value from the equation
// y(x,t) = A*exp(-(x-xf)*(x-xf)/(aa*aa)
float x = 0.0;
float dx = 10.0;
for (int i = 0; i < yvalues_1.length; i++)
{
xf_1 = xi_1 + vel_1*t;
yvalues_1[i] = amplitude_1*exp(-(x-xf_1)*(x-xf_1)/(aa_1*aa_1));
xf_2 = xi_2 + vel_2*t;
yvalues_2[i] = amplitude_2*exp(-(x-xf_2)*(x-xf_2)/(aa_2*aa_2));
x+=dx;
}
}
void renderPackets()
{
// A simple way to draw the wave with an ellipse at each location
for (int i = 0; i < yvalues_1.length; i++)
{
noStroke();
fill(255,50);
ellipseMode(CENTER)
ellipse(i * xspacing, width/2 + yvalues_1[i] + yvalues_2[i] - 200, 16, 16);
}
}


The reader should note that the interference in this computer simulation occurs in
the renderPackets() method where the y-coordinate of the circle is passed to
the ellipse() method as yvalues_1[i] + yvalues_2[i]. To simulate
destructive interference of pulses one should change the amplitude of one of the
pulses from +175 to -175 while leaving the other amplitude unchanged.

Figures 1 and 2 at the end of this paper depict constructive interference of two
pulses. Figure 1 shows the pulses as they approach each other while Figure 2 shows
the pulses as the overlap.

There are many phenomena related to constructive and destructive interference of


traveling waves. The famous double slit experiment carried out by Young in 1803
demonstrated that light is purely a wave phenomenon. Two types of interference
that may be easily simulated with our formalism are beats and standing waves.

Beats is the name given to the phenomenon that occurs when two waves of slightly
different frequencies occupy the same place at the same time. In the classroom beats
are typically demonstrated with sound waves. By striking two tuning forks that
vibrate at slightly different frequencies students hear a sound pattern the
alternatively gets louder then quieter then louder then quieter, etc. The loud sounds
are the result of constructive interference and the quieter sounds are the result of
destructive interference. The frequency at which the loud sounds are heard is
referred to as the beat frequency and it may be shown that the beat frequency
equals the absolute value of the difference between the frequency of the first tuning
fork and the frequency of the second tuning fork.

To simulate beats with our program we create two travelling waves moving in the
same direction but at slightly different frequencies. When the program is run an
alternating band of constructive and destructive interference pattern moves across
the screen. The frequency with which the constructive interference pattern recurs is
a measure of the beat frequency. A complete program written in the Processing
language that simulates two traveling waves with different frequencies, both
moving from left to right is given below.

float tt = 0.0;
// time
float dtt = 1.0; // time increment
int numParticles = 150/* - 9*/;
float amplitude = 175.0;
float speed = 20;
int xspacing = 8;
int nn = 3;
float length = (numParticles-1) * xspacing;
float period = (2.0 * length)/(speed * nn);
float wavelength = speed * period;
float k = 2.0*PI/wavelength;
float w = 2.0*PI/period;
float periodPrime = period + 5;
float wavelengthPrime = periodPrime*(wavelength/period);
float kPrime = 2.0*PI/wavelengthPrime;
float wPrime = 2.0*PI/periodPrime;
boolean bPause = false;
float[] yvalues;
void setup()
{
size(1200, 800);
frameRate(30);
colorMode(RGB,255,255,255,100);
smooth();
yvalues = new float[numParticles];
}
void draw()
{

if ( !bPause ) {
background(0);
calcWave(tt);
renderWave();
tt += dtt;
}
}
void keyPressed()
{
if ( key == 'p' )
bPause = true;
else
bPause = false;
}
void calcWave(float t)
{
float x = 0.0;
float dx = xspacing;
for (int i = 0; i < yvalues.length; i++)
{
yvalues[i] = amplitude * sin(k*x - w*t) +
amplitude * sin(kPrime*x - wPrime*t) - 200;
x+=dx;
}
}
void renderWave()
{
for (int i = 0; i < yvalues.length; i++)
{
stroke(255,0,0);
line(400, 0, 400, 1000);
line(0,400,1200,400);
noStroke();
fill(255,50);
ellipseMode(CENTER);
ellipse(i * xspacing, width / 2 + yvalues[i], 16, 16);
}
}

Note that the beat frequency in this example is 5 per the line that states

float periodPrime = period + 5;
Our finally example of interference is standing waves. Standing waves are the basis
of all string musical instruments such as guitars and pianos. Waves are set up in taut
strings by plucking or striking the string. The disturbance propagates outward from
the point at which it originated and is reflected in the opposite direction when it
strikes the fixed ends at either side of the string. This results in two waveforms
travelling in opposite directions through the same medium. It is a straightforward
matter to simulate standing waves with our formalism. Whereas beats are simulated
by creating two travelling waves with different frequencies traveling in the same
direction, standing waves may be simulated by created two standing waves with the
same frequency traveling in opposite directions. Standing wave patterns do not
occur for all frequencies. A mathematical analysis shows that only frequencies that
obey the relationship


fn = n(v/2L) where n = 1, 2, 3,

In this equation v represents the speed of the traveling waves in the taut string, L
represents the length of the string and n represents a positive integer. Different
standing wave patterns result from frequencies corresponding to different values of
n. As n increases the frequency increases and since the speed of the traveling wave
remains the same, the wavelength of the standing wave decreases. A complete
program written in the Processing language that simulates two traveling waves with
same frequency moving in opposite directions is given below.

float tt = 0.0;
// time
float dtt = 1.0; // time increment
int numParticles = 150/* - 9*/;
float amplitude = 175.0;
float speed = 5;
int xspacing = 8;
int nn = 3;
float length = (numParticles-1) * xspacing;
float period = (2.0 * length)/(speed * nn);
float wavelength = speed * period;
float k = 2.0*PI/wavelength;
float w = 2.0*PI/period;
boolean bPause = false;
float[] yvalues;
void setup()
{
size(1200, 800);
frameRate(30);
colorMode(RGB,255,255,255,100);
smooth();
yvalues = new float[numParticles];
}
void draw()
{
if ( !bPause )
{
background(0);
calcWave(tt);
renderWave();
tt += dtt;
}
}
void keyPressed()
{
if ( key == 'p' )
bPause = true;
else
bPause = false;
}

void calcWave(float t)
{
float x = 0.0;
float dx = xspacing;
for (int i = 0; i < yvalues.length; i++) {
yvalues[i] = amplitude * sin(k*x - w*t) + amplitude * sin(k*x + w*t) - 200;
x += dx;
}
}
void renderWave()
{
for (int i = 0; i < yvalues.length; i++)
{
stroke(255,0,0);
line(400, 0, 400, 1000);
line(0,400,1200,400);
noStroke();
fill(255,50);
ellipseMode(CENTER);
ellipse( i * xspacing, width/2 + yvalues[i], 16, 16);
}
}

The reader should note two details of the above code. First, in the calcWave()
method the line

yvalues[i] = amplitude * sin(k*x - w*t) +
amplitude * sin(k*x + w*t) - 200;
yields two waves of the same frequency traveling in opposite directions by passing
k*x w*t to the first sine function and k*x + w*t to the second sine function.
The common k yields the common frequency and the switch from a minus sign to
a plus sign yields the opposite directions of motion. Second, the standing wave
pattern displayed may be controlled by setting the integer n in the line

int nn = 3;

When nn is set to 1 the pattern has two nodes, one antinode, and fits half a
wavelength (1/2) into the fixed length of the string. When nn is set to 2 the pattern
has three nodes, two antinodes, and fits one wavelength (2/2) into the fixed length
of the string. When nn is set to 3 the pattern has four nodes, three antinodes, and
fits one and a half wavelengths (3/2) into the fixed length of the string (see Figure 3
at the end of this paper). The patterns continue and a student may investigate
standing waves of increasing frequency and decreasing wavelength by simply
changing the value of the variable nn and running the program again.


Conclusion

The examples presented above are only a small sample of the topics in physics
where instruction may be enhanced by computer simulations. Once a student is
empowered with the skill set of writing simulation programs (in Processing or any
other programming language) he/she is only limited his/her imagination when it
comes to studying and understanding just about any topic in physics.

References

Reas, Casey and Fry, Ben. Processing: A Programming Handbook for Visual Designers
and Artists. The MIT Press, 2007.

Shiffman, Daniel. The Nature of Code. Daniel Shiffman, 2012.

Cutnell, John D. and Johnson, Kenneth W. Physics. John Wiley & Sons, Inc., 2007.

Figures



Figure 1. Two pulses, both with up orientation approaching each other.







Figure 2. Constructive interference of two pulses as they overlap.



Figure 3. A standing wave pattern (n = 3) depicting 4 nodes and 3 anti-nodes.

Das könnte Ihnen auch gefallen