This research explores using physics to create computational music. In this project, we investigate the dynamics of a bouncing ball on a staircase and its application in generating musical notes using Mathematica. The objective of our research is to model the trajectory of a bouncing ball influenced by gravity and initial conditions, and to translate its kinetic behavior into musical expressions. Parameters such as the initial velocity of the ball, the number of stairs, and the number of balls are adjustable. As a result, the animation is capable of generating a variety of melodies.
The animation utilizes solutions to differential equations to simulate the ball’s motion, accounting for bounces and energy loss. The horizontal position of the ball (x-coordinate) determines the pitch of the generated musical notes, while the timing of the bounces dictates the rhythm. The result of our research is a three-dimensional animation of the bouncing ball displayed with a synchronized audio track playing.
The animation utilizes solutions to differential equations to simulate the ball’s motion, accounting for bounces and energy loss. The horizontal position of the ball (x-coordinate) determines the pitch of the generated musical notes, while the timing of the bounces dictates the rhythm. The result of our research is a three-dimensional animation of the bouncing ball displayed with a synchronized audio track playing.
Introduction
Introduction
This project aims to create an animation of a bouncing ball that generates music based on its trajectory.
The process is divided into the following stages:
◼
Computing: calculating the ball’s trajectory and the points at which the ball bounces using differential equations
◼
Animating: creating the visualization of the ball’s path using mathematical functions
◼
Audio: generating audio that is synchronized with the animation
◼
Expanding: adding controls, adjustable parameters and options; improving the movement of the ball
Modeling the ball’s trajectory
Modeling the ball’s trajectory
To model the bouncing ball’s trajectory, we can use solutions to differential equations. Let be the position of the ball given time At let us set the ball to be at position where is the initial height of the ball. For simplification, we only want the ball to have velocity in the x-direction initially, so we set (0)(0)0 and (0), where is the initial velocity of the ball. We also neglect all forces except the gravitational force, so we set (t)(t)0, and (t)-g, where For now, let us consider a static case: the ball is bouncing on a 4-step staircase with initial height 5, an initial velocity of 1, and a runtime of 10 seconds.
(x(t),y(t),z(t))
t.
t0,
(0,0.5,),
h
i
h
i
′
y
′
z
′
x
v
i
v
i
′′
x
′′
y
′′
z
g9.81m.
2
s
h
i
v
i
t
max
In[]:=
g=9.81;numSteps=4;heighti=5;velocityi=1;runtime=10;
The function solves for the functions in a differential equation given a set of equations. Before we can use the solver, we must first define a set of equations, as well as add a staircase and account for the bouncing motion:
NDSolve
In[]:=
{x[0]==0,y[0]==0.5,z[0]==heighti,x'[0]==velocityi,y'[0]==0,z'[0]==0,x''[t]==0,y''[t]==0,z''[t]==-g};
Adding a staircase
Adding a staircase
Let be a function that models a staircase. The function inside is used to model the staircase. Whenever the x-position of the ball is an integer, we want to create a step until the height reaches 0.
a(t)
WhenEvent
NDSolve
In[]:=
WhenEvent[Mod[x[t],1]==0,If[a[t]>0,a[t]->a[t]-1,"RemoveEvent"]];
Modeling the bouncing motion
Modeling the bouncing motion
When the ball hits one of the stairs, we want the ball to bounce off with 90% of its previous velocity. To model this, we negate the coordinate while multiplying the and velocities by Next, we want to store the points where the trajectory of the ball and the staircase intersect. The function is used to obtain the coordinates of the bounces and the times of the bounces.
z
x,y,
z
0.9
Sow
The following code models the bouncing motion of the ball. The intersection points are stored in the form :
{x,y,z,t}
In[]:=
WhenEvent[{z[t]==a[t]},{{x'[t],y'[t],z'[t]}->0.9{x'[t],y'[t],-z'[t]},Sow[{x[t],y[t],z[t],t}]}];
Storing the position functions and contact points
Storing the position functions and contact points
Combining all the previous code, we get the following:
In[]:=
{ballsteps,{points}}=NDSolve[{x[0]==0,y[0]==0.5,z[0]==heighti,x'[0]==velocityi,y'[0]==0,z'[0]==0,x''[t]==0,y''[t]==0,z''[t]==-g,a[0]==numSteps,WhenEvent[Mod[x[t],1]==0,If[a[t]>0,a[t]->a[t]-1,"RemoveEvent"]],WhenEvent[{z[t]==a[t]},{{x'[t],y'[t],z'[t]}->0.9{x'[t],y'[t],-z'[t]},Sow[{x[t],y[t],z[t],t}]}]},{x,y,z,a},{t,0,runtime},DiscreteVariables->{a}]//Reap;
The list stores the parametric functions and .
ballsteps
x(t),y(t),z(t),
a(t)
In[]:=
ballsteps
Out[]=
xInterpolatingFunction,yInterpolatingFunction,zInterpolatingFunction,aInterpolatingFunction
The list stores the intersection points between the ball’s trajectory and the staircase and the times of intersection in the form
points
{x,y,z,t}.
In[]:=
points
Out[]=
{{0.451524,0.5,4.,0.451524},{1.36397,0.5,3.,1.46536},{2.38116,0.5,2.,2.72114},{3.41626,0.5,1.,4.14104},{4.42637,0.5,0.,5.6806},{5.31493,0.5,0.,7.18538},{6.03466,0.5,0.,8.53968},{6.61764,0.5,0.,9.75856}}
Generating an animation
Generating an animation
Making the staircase
Making the staircase
First, let us plot a 3-D staircase. allows us to generate a plot of a three-dimensional function. The graph of the function is convenient for replicating the staircase.
Plot3D
Floor
In[]:=
Plot3D[{Floor[numSteps+1-x]},{x,0,runtime*velocityi},{y,0,1},PlotRange->{{0,runtime*velocityi},{0,1},{0,heighti*1.1}},PlotStyle->White,Filling->Bottom,Exclusions->None,Axes->False,Mesh->True,MeshFunctions->(#3&),PlotPoints->ControlActive[20,40],MaxRecursion->ControlActive[2,4],Boxed->False]
Out[]=
Adding the ball
Adding the ball
Using we create a point that is centered at the position of the ball. We can use to get the position of the ball at any time
Graphics3D,
ballsteps
t.
In[]:=
Graphics3D[{Blue,PointSize[0.025],Point[{ballsteps[[1,1,2]][t],ballsteps[[1,2,2]][t],ballsteps[[1,3,2]][t]+0.025}]}];
We use to display both the staircase and ball simultaneously.
Show
Running the following code displays the animation at t=0:
Animating the plot
Animating the plot
Playing the sound
Playing the sound
We run the following code to get the times between each bounce, in other words, the durations of the notes.
Now we must get the pitches of the notes based on the x-coordinate of the ball. In Mathematica, 0 represents the middle-C pitch, and an integer n represents a pitch n semitones away from the middle-C. We store the x-coordinates into a list, then take the floor of each coordinate to get the pitches.
Combining the audio and the animation, we get the following:
Creating a DynamicModule
Creating a DynamicModule
Adding a start/reset button
Adding a start/reset button
Start button:
Reset button:
Adding adjustable initial conditions and different instruments
Adding adjustable initial conditions and different instruments
The following code allows the user to input the initial conditions of the ball:
Image of the input interface:
(Subsequent visualizations do not display the input field section of the interface, but do display the main output)
(Subsequent visualizations do not display the input field section of the interface, but do display the main output)
Implementing multiple balls
Implementing multiple balls
Generating different pitches
Generating different pitches
In the above code, every ball generates the same pitches. We adjust the code to make each ball generate a different pitch to make the sounds more interesting.
Adding this to our code, we get the following:
Example animation with 2 balls
Example animation with 2 balls
Adding more interesting movement
Adding more interesting movement
To make the movement of the balls more interesting, we can make them move side-to-side as shown below.
The following code contains the final version of our animation, updated with more interesting ball movement:
Conclusion & Future Directions
Conclusion & Future Directions
We were able to successfully generate an animation of a ball that plays music based on its bounces. We were also able to expand our project to include adjustable conditions, instruments, and number of balls.
In the future, I wish to expand my project so that it produces more interesting sounds. For example, I want to implement a feature where the balls collide in the air and produce additional sounds. This will increase the potential of the project to be able to generate more melodies. An idea that I have is to play the Super Mario Bros Theme with bouncing balls. Another idea that I have is that instead of balls, I could use cubes or tetrahedrons to play the music, with each face representing a different pitch. I also hope to include a feature where a user is able to import an audio file and the simulation will create a staircase with different-sized steps that replicates the melody. Finally, I hope to improve the interface of the animation with various colors and steps that light up when touched.
Acknowledgements
Acknowledgements
I would like to thank my mentor, Carlos Angulo, for providing support throughout the process of coding. I would also like to thank the Wolfram High School Summer Research Program for granting me the resources and opportunities to create this project.
References
References
Simulate a Bouncing Ball. (2024). Wolfram.com. https://reference.wolfram.com/language/example/SimulateABouncingBall.html
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Generating musical notes based on the trajectory of bouncing balls
by Ian Gu
Wolfram Community, STAFF PICKS, July 12, 2024
https://community.wolfram.com/groups/-/m/t/3215610
by Ian Gu
Wolfram Community, STAFF PICKS, July 12, 2024
https://community.wolfram.com/groups/-/m/t/3215610