首页 > > 详细

讲解CSE1010、辅导Python编程、讲解Python、辅导Python设计解析R语言编程|辅导Python程序

HW 5: N-Body Simulation
CSE1010 Fall 2018
Jeffrey A. Meunier
University of Connecticut
Table of Contents
1. Introduction
2
2. Value
2
3. Due Date
2
4. Objectives
3
5. Background
3
5.1. Vector components
3
5.2. Turtle graphics
4
5.3. Parallel lists
6
5.4. Plural list names
8
5.5. Dot notation
9
6. Assignment 10
6.1. Program file 10
6.2. Initial statements 12
6.3. Modify the main function 14
6.4. Add a newTurtle function 14
6.5. Add a printBody function 16
6.6. Add an initBody function 16
6.7. Add a setup function 18
6.8. Add a moveBody function 20
6.9. Add a moveBodies function 22
6.10. Add a calculateForce function 24
6.11. Add an accelerateBody function 26
6.12. Add an accelerateBodies function 28
6.13. Let the animation run longer 29
6.14. Use better numbers 30
7. Report 30
8. Submission 31
9. Grading Rubric 322
1. Introduction
This project is a discrete simulation solution of an N-body gravitational force problem.
Given some number of bodies in empty space, the bodies are allowed to move freely and
interact with each other under gravitational force, although in this simulation you will not
simulate collisions between the bodies. The result yields an interesting animation.
That image is a screen shot of an animation that had 5 initial bodies. Three of them have
left the screen already and two are orbiting each other.
2. Value
This program is worth a maximum of 20 points. See the grading rubric at the end for a
breakdown of the values of different parts of this project.
3. Due Date
This project is due by 11:59pm on Sunday, October 7, 2018. A penalty of 20% per day
will be deducted from your grade, starting at 12:00am on Monday.3
4. Objectives
The purpose of this assignment is to give you experience using:
Parallel lists
Loops
Functions, parameters, return values
Turtle graphics
Global variables
Pythagorean Theorem
5. Background
Be sure you understand how to write and use for loops and while loops.
Be sure you understand how to write and use functions, including parameters, return
values, and arguments.
Read at least the introduction section of this article about the N-body problem.
5.1. Vector components
Here is a point on the Cartesian plane.
We can give the point a velocity in a certain direction, and we can represent that as this
vector. The vector has a specific length and is oriented at a specific angle:4
Using the Pythagorean Theorem we know that the length of that vector is 5, and so we
would say that the velocity of that point is 5, and the angle happens to be about 53.13
degrees.
We can decompose the vector into two vectors that are parallel to the X and Y axes:
The pair of vectors are equivalent to the single vector shown in image 2. Thus, this point
has Vx (meaning velocity in the X direction) of 3 and Vy of 4.
When dealing with motion of bodies on a Cartesian plane, these X and Y vectors can be
much easier to use than the single angled vector would be.
5.2. Turtle graphics
Here is a turtle graphics example. Enter these commands into Python.
>>> import turtle
>>> t = turtle.Turtle()
A new graphical window opens with the "turtle" in the middle of it.
>>> t.forward(100)5
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
You can do a lot with turtle graphics in Python. Have a look at the online documentation:
https://docs.python.org/3.3/library/turtle.html
Note that I use turtles a little differently here than they do in that tutorial. In the tutorial it
is assumed that there is only one turtle. Thus, all the turtle motion commands like
forward, right, and left will affect that single turtle. In this assignment we will need
more than one turtle, so we will address them as turtle-n.forward, turtle-n.right,
and so on. In my statement examples above, turtle-n is just the variable t.
For example you can create multiple turtles like this:
>>> t1 = turtle.Turtle()
>>> t2 = turtle.Turtle()
and so on. Each of those turtles can be controlled independently.6
Note that the variable names t1 and t2 are completely arbitrary. I could have used the
variables a and b or x and y.
Another way to move a turtle is by using the goto method.
>>> import turtle
>>> t = turtle.Turtle()
>>> t.goto(200, 100)
This is how you'll move the turtles in this assignment.
5.3. Parallel lists
Parallel lists are lists whose elements at the same indexes are related.
Here is a table of points in the Cartesian plane:
X Y
1. 100 35
2. 47 -80
3. -12 15
Row 1 contains the coordinate values for point number 1, and I've highlighted that row in
green. Row 2 contains the values for point 2. The same is true for row 3.
You can also consider individual columns in a table. Here I have highlighted the X column
in green:
X Y
1. 100 357
2. 47 -80
3. -12 15
Each column is a list of numbers. Column X contains the list of numbers 100, 47, and -12.
Column Y contains 35, -80, 15.
Now consider this simplified table:
X Y
100 35
47 -80
-12 15
The row numbers are now implicit, but you and I know that the rows still have numbers. If
I asked you for the values in row 1, you'd still be able to find them. The best part is that
simplified table is easy to implement in Python.
The simplest way to store this table in Python is to use two separate lists, one for column X
and one for column Y. First we can rotate the table horizontally:
X 100 47 -12
Y 35 -80 15
And then it's easy to convert those lists into Python assignment statements:
X = [100, 47, -12]
Y = [35, -80, 15]
It's also easy to add columns to the table by creating new lists.
Vx = [0.0, 1.1, -3.6]
Vy = [-2.4, -3.8, 0.7]
Mass = [77.3, 120.9, 61.4]
And thus we have a table that is represented in Python as a group of lists. Below I show
the lists together with one of the "rows" of the table highlighted in orange (remember that
each list represents one column of the table, and that these lists as a group are the table on
its side):
X = [ 100, 47, -12]
Y = [ 35, -80, 15]
Vx = [ 0.0, 1.1, -3.6]8
Vy = [-2.4, -3.8, 0.7]
Mass = [77.3, 120.9, 61.4]
These lists are called "parallel" lists because their values were meant to be accessed at a
specific location in parallel. That means that if you retrieve the X value at location 0, you're
very likely also to need the Y value at location 0, and also the Vx, Vy, and Masses values
at location 0. What you wouldn't do is get the X value at location 0, then the Y value at
location 1, the Vx value at location 2, and so on, because those values are in no way
related.
In this assignment you'll use a number of parallel lists like this. The lists represent a
number of free-floating bodies interacting with each other under the force of gravity. Each
body is represented by one "row" of the table.
Body 0:
X[0], Y[0], Vx[0], Vy[0], Mass[0]
Body 1:
X[1], Y[1], Vx[1], Vy[1], Mass[1]
Body 2:
X[2], Y[2], Vx[2], Vy[2], Mass[2]
Here's a for loop that displays the information for each of the bodies stored in the table:
for n in range(3):
print('Body', n, 'has these properties:')
print('X', X[n])
print('Y', Y[n])
print('Vx', Vx[n])
print('Vy', Vy[n])
print('Mass', Mass[n])
5.4. Plural list names
In the previous section I used variable names X, Y, Vx, Vy, and Mass to store lists. But
usually when I store a list of values in a variable I will name the variable something plural.
Thus Mass becomes Masses, so instead of this:
Mass = [77.3, 120.9, 61.4]9
I would use this:
Masses = [77.3, 120.9, 61.4]
Likewise X becomes Xs, Y becomes Ys, Vx becomes Vxs, and Vy becomes Vys. This is
useful to remind you that each of these variables contains more than one thing. This is the
variable naming convention I use in this project.
5.5. Dot notation
These are the turtle graphics statements you used to draw a square:
>>> import turtle
>>> t = turtle.Turtle()
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
These statements use a strange dotted notation:
turtle.Turtle
t.forward
t.left
and so on.
The dot is a way of referring to a thing that's stored inside another thing. For example, the
turtle module has a thing in it called Turtle (that thing is a class, which is something
we'll talk about later in the semester). Thus the statement turtle.Turtle() causes
Python to create a new instance of the Turtle class that's found in the turtle module.
I used an assignment statement to store the Turtle instance in the variable called t. That
instance of the Turtle class has things in it, too. It has functions called forward, left,
right, and many others. You can have a look at what t.forward actually is:
>>> t.forward
0x112063cc0>>10
Think of a bound method as a function: you call it with arguments and it does something.
Later this semester we'll talk about what the difference is between a method and a
function.
calling the function t.forward(100) is similar to a function call written like this:
forward(t, 100)
except that there is no function called forward that you can use in this way.
Just know that if you call a function but that function has this form:
something . function_name ( arguments )
then the function is more properly called a method. Thus forward and left are methods,
even though you call them just like functions.
6. Assignment
In your CSE1010 folder create a new folder for this homework assignment.
6.1. Program file
Summary
Here I show you a common way to structure a python program file. It contains an internal
test to determine if it is run as a main program file or included as a module in some other
program.
Do this
Start IDLE and copy this program and save it under the file name nbody.py.
# N-Body Simulation
# CSE1010 Homework 5, Fall 2018
# (your name goes here)
# (the current date goes here)
# (TA: your TA's name goes here)
# Lab section: (your lab section number goes here)
# Instructor: (your lecturer's name goes here)
def main():
print('N-Body simulation starting')11
print('Program finished')
if __name__ == '__main__':
main()
Be sure to change those comments appropriately to add your own information.
Run it in IDLE to be sure it works correctly:
======== RESTART: /Users/jeff/CSE1010/HW4-NBody/nbody.py ========
N-Body simulation starting
Program finished
>>>
The last if statement in that program does the following:
If the program is run as a main program (meaning it's run using F5 from IDLE), then
the main function is called. Be aware that there is nothing special about the
function main, it's just the name I chose to represent the "main" part of the
program. I could have chosen the name start or do_this or almost any other
function name.
If the program is run in any other manner (such as if the file is imported into
another program file) then the main function is not called.
It's proper Python programming to have an if statement like that in each of your program
files.
Let's test this out to see how it actually works. Change the nbody.py file to add the
following else clause to the if statement:
if __name__ == '__main__':
main()
else:
print('Not calling the main() function')
Now in the Python Shell type these statements:
>>> nbody
Traceback (most recent call last):
File "", line 1, in
nbody
NameError: name 'nbody' is not defined12
That verified that the nbody module was not loaded yet.
>>> import nbody
Not calling the main function()
Python has distinguished calling your function as a main program and importing it as a
module.
Keep typing:
>>> nbody

That shows that the nbody module is now defined.
>>> nbody.main

That just showed that the main function is available inside the nbody module. In order to
call the function you need to use parentheses after it:
>>> nbody.main()
N-Body simulation starting
Program finished
That shows that even though the main function was not called automatically, it is still
available for us to call after the module has been imported.
6.2. Initial statements
Summary
Here you will define some variables that will be used throughout your program. In
particular there is a set of parallel lists that will represent different characteristics of a set of
bodies in motion under gravitational attraction.
Do this
Back in your nbody.py file, delete the else clause (and the print statement under it) from
the if statement in your program file. That shouldn't be in an actual program. I had you
add it there just for testing.
Then add these statements after the header comment block but before the def main()13
statement.
import math, random, time, turtle
NBodies = 5
G = 5
SpaceRadius = 250
MinMass = 5
MaxMass = 100
MaxVelocity = 100
BodyColor = 'black'
TraceColor = 'green'
Turtles = []
Masses = []
Xs = []
Ys = []
Vxs = []
Vys = []
OffScreen = []
WinX2 = 0
WinY2 = 0
These are the initial values and lists that your program will need.
Explanation:
The first 8 assignment statements set up some global constants. These determine the
look of your program and will be used to determine initial values of other variables.
Use these values to start with. You can change them around later to see how they
affect your program.
Turtles: This program will use some number of turtles to draw graphics on the
screen. Each turtle will be stored in this list.
Masses: This lists the masses of all the bodies.
Xs, Ys: These two lists store the x and y coordinate values of each of the bodies. The
bodies will exists in a 2-dimensional Cartesian plane.
Vxs, Vys: These are the x and y components of the velocities of the bodies.
OffScreen: This will keep track of which bodies have left the viewing are. This list
can be checked periodically and when all bodies leave the viewing area the
program will stop.
WinX2, WinY2: These are values that we'll use to determine when a body leaves
the viewing area.14
6.3. Modify the main function
Summary
Here you will add some statements to the main function to start the turtle graphics
window and determine its size.
Do this
Early in the assignment I'll give you a lot of the program in order to get you started. As the
assignment progresses I'll leave more of the programming to you.
Change your main function to look like this:
def main():
print('N-Body simulation starting')
screen = turtle.Screen()
screen.title('N-Body Simulator')
global WinX2, WinY2
WinX2 = screen.window_width() / 2
WinY2 = screen.window_height() / 2
print('Program finished')
screen.mainloop()
The final statement screen.mainloop() keeps the turtle graphics window on the screen
until you quit the program explicitly.
Test it
Run this program to see how it works. It should open an empty window and then wait for
you to close it.
6.4. Function newTurtle
Summary
This function will be responsible for creating a new turtle and initializing it to have the
settings needed for this program.
Do this
Create a new function in your program called newTurtle. This function has no
parameters.
All the functions should go above the main function, but below all the initial assignment
statements.15
The program file should be organized like this:
...
OffScreen = []
WinX2 = 0
WinY2 = 0
def newTurtle():
you're going to write the body of this function
def main():
print('N-Body simulation starting')
...
Please separate the functions and other major sections of your program with single blank
lines, like I show there.
Inside the newTurtle function you need to write statements to do this:
1. Create a new turtle with the turtle.Turtle() statement and store it in a variable. The
variable name is arbitrary, and this will end up being a variable that's local to the
newTurtle function.
2. Append the turtle in this variable to the list of turtles found in the Turtles variable.
Read about how to use the append method here: https://docs.python.org/3/tutorial/
datastructures.html
Note that the Turtles variable has already been defined near the beginning of the
program file.
3. Set the turtle's speed to 0 and its pensize to 5. See this web page for more
information: https://docs.python.org/3.3/library/turtle.html
4. Return the turtle from this function. The turtle is found in the variable that you created
in the first step.
Test it
Add these two statements to the main function between the statements shown in gray:
WinY2 = screen.window_height() / 2
t = newTurtle() ← new16
t.forward(100) ← new
print('Program finished')
Run the program. It should look like this:
If your program does not look like that then do not proceed until you have fixed what's
wrong.
6.5. Function printBody
Add this function to your program:
def printBodyInfo(n):
print('Body', n, 'mass =', Masses[n], ', x =', Xs[n], ', y =',
Ys[n], ', vx =', Vxs[n], ', vy =', Vys[n])
You will not be able to test this function until after you finish the next two functions. You
will use this function to diagnose any possible problems with those functions.
6.6. Function initBody
Summary
This function will treat a turtle as if it were a body in space, like a planet or a star. The
function will be responsible for giving the body a mass, a location in space, and a velocity
in some direction. All these values will be chosen randomly.
This function will also add these values to the Masses, Xs, Ys, Vxs, Vys, and OffScreen17
lists. Thus, for each new body that's initialized, its values will be placed at the ends of
those lists. After (for example) 4 bodies have been initialized, Masses[0] is the mass of
the first body, Xs[0] and Ys[0] are its location, and Vxs[0] and Vys[0] are its velocity.
The same is true for the second body: its index values are all 1. The same is true for bodies
numbered 2 and 3.
Do this
Create a new function called initBody. It has a single parameter: this function expects
the parameter variable to contain a turtle. Thus, the parameter name will probably be
something like t or turt. Do not use the name turtle, though -- that name refers to the
turtle module.
These are the steps to do inside this function:
1. Generate a random mass (the mass is just a number) in the range MinMass to MaxMass.
Append this value to the list of Masses. Use random.randint to generate a random
number. Google it if you don't remember how to use it.
2. Use the turtlesize method to set the size of the turtle to be mass * 0.03. See the
turtlesize method here:
https://docs.python.org/3.3/library/turtle.html?highlight=turtle#turtle.turtlesize
Use the same value for stretch_wid and stretch_len. You don't need to specify an
argument for outline.
3. Set the turtle's shape to 'circle'. It's in the same web page.
4. Generate a random X-location for the turtle in the range -SpaceRadius to
SpaceRadius. Append that number to the Xs list.
5. Do the same for the Y-location of the turtle. Append it to the Ys list.
6. Generate a random X-velocity in the range -MaxVelocity to MaxVelocity. Divide it
by 100 (this just helps to slow down the simulation). Then append it to the Vxs list.
7. Do the same for the Y-velocity. Append it to the Vys list.
8. Append the value False to the OffScreen list.
9. Call penup on the turtle, have it goto the location x and y that you generated randomly
just a few statements back, and then call pendown. The web page contains all the
information you need on those statements.18
Test it
Delete the t.forward(100) statement in the main function. Replace it with these two
statements:
t = newTurtle()
initBody(t) ← new
printBodyInfo(0) ← new
Make sure it's indented so that it's properly inside the main function.
Run the program. It should show the same window but now the body is a circle and it's
not in the center of the screen.
Also notice the output in the Python Shell window:
N-Body simulation starting
Body 0 mass = 67 , x = 115 , y = -92 , vx = 0.47 , vy = 0.21
Program finished
Exit the program and run it a few more times. The body should show up in a different
location each time and have a different size.
6.7. Function setup
Summary
Now that you got the two functions newTurtle and initBody working, you will call
them inside a loop in order to create a number of bodies.19

联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!