Projectile Motion with Python, Desmos, and Monte Carlo Simulation
I’ve written about my backwards approach to to projectile motion previously here, here, and here.
I had students solving the warm-up problem to that first lesson, which goes like this:
A student is at one end of a basketball court. He wants to throw a basketball into the hoop at the opposite end.
What information do you need to model this situation using the Geogebra model? Write down [______] = on your paper for any values you need to know to solve it using the model, and Mr. Weinberg will give you any information he has.
Find a possible model in Geogebra that works for solving this problem.
At what minimum speed he could throw the ball in order to get the ball into the hoop?
The students did what they usually do with the Geogebra projectile motion model and solved it with some interesting methods. One student lowered the hoop to the floor. Another started with a 45 degree angle, and then increased the speed successively until the ball made it into the hoop. Good stuff.
A student’s comment about making lots of guesses here got me thinking about finding solutions more algorithmically. I’ve been looking for new ways to play around with genetic algorithms and Monte Carlo methods since they are essentially guess and check procedures made productive by the power of the computer.
I wrote a Python program that does the following:
- Get information about the initial characteristics of the projectile and the desired final location.
- Make a large number of projectiles (guesses) with random values for angle and initial speed within a specified range.
- Calculate the ending position of all of the projectiles. Sort them by how far they end up compared to the desired target.
- Take the twenty projectiles with the least error, and use these values to define the initial values for a new, large number of projectiles.
- Repeat until the error doesn’t change much between runs.
- Report the projectile at the end with the least error.
- Report the entire procedure a number of times to see how consistent the ‘best’ answer is.
I’ve posted the code for this here at Github.
As a final step, I have this program outputting commands to graph the resulting projectile paths on Desmos. Pasting the result into the console while a Desmos calculator open, makes a nice graph for each of the generated projectiles and their intersecting at the desired target:
This is also on a live Desmos page here.
This shows that there is a range of possible answers, which is something I told my physics class based on their own solutions to the problem. Having a way to show (rather than tell) is always the better option.
I also like that I can change the nature of the answers I get if I adjust the way answers are sorted. This line in the code chooses how the projectile guesses are sorted by minimizing error:
self.ordered = self.array.sort(key=lambda x: abs(x.error))
If I change this to instead sort by the sum of error and the initial speed of the projectile, I get answers that are much closer to each other, and to the minimum speed necessary to hit the target:
Fun stuff all around.