代做CSE1010作业、代写Python编程作业、代做Python实验作业、代写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 32
2
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 35
7
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
<bound method TNavigator.forward of <turtle.Turtle object at
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 "<pyshell#2>", line 1, in <module>
nbody
NameError: name 'nbody' is not defined
12
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
<module 'nbody' from '/Users/jeff/CSE1010/HW4-NBody/nbody.py'>
That shows that the nbody module is now defined.
>>> nbody.main
<function main at 0x1122e98c8>
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() ← new
16
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 OffScreen
17
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
Do this
Add a function called setup that has no parameters.
1. Add this statement to the beginning of the function:
turtle.tracer(0, 0)
Be sure to indent it properly That function call causes all turtle animations not to produce
any output until the update function is called later. This dramatically speeds up any turtle
graphics statements that are done since the display is updated only once when the update
function is called.
2. Create a for loop that iterates over the number of bodies, which is found in the
variable called NBodies. Use the range operator.
3. Inside the loop, call the newTurtle function and store that function's return value in a
variable.
4. Still inside the loop, call the initBody function on the turtle found in that variable.
5. Still inside the loop, call the printBodyInfo on that turtle.
6. Add this statement after (below, outside) the loop:
turtle.update()
Be sure that statement is not part of the loop but is part of the function body.
Test it
In the main function, replace these statements:
t = newTurtle()
initBody(t)
printBodyInfo(0)
with this statement:
setup()
Run the program. Five bodies should be placed randomly in the window:
20
The Python Shell window should show the details of the five bodies:
N-Body simulation starting
Body 0 mass = 75 , x = -225 , y = 101 , vx = -3.1 , vy = 9.1
Body 1 mass = 69 , x = -192 , y = -218 , vx = -8.8 , vy = -7.7
Body 2 mass = 8 , x = 107 , y = 160 , vx = -9.6 , vy = -0.6
Body 3 mass = 23 , x = -44 , y = 154 , vx = -5.7 , vy = 6.6
Body 4 mass = 41 , x = 33 , y = 67 , vx = 8.3 , vy = -7.7
Program finished
Make sure that the values shown for mass, x, y, vx, and vy are all within the correct
range. If any of the values is in the wrong range, do not proceed until you have fixed the
problem.
6.8. Function moveBody
Summary
This function will be responsible for moving a body according to its values in the Xs, Ys,
Vxs, and Vys lists.
At each time step, the location of a body changes by its velocity. For example, if a body is
moving at 3 meters per second in the +X direction and 4 meters per second in the +Y
direction, then each second the location of the body must increase by 3 in the X direction
and increase by 4 in the Y direction.
After this function is written (in the next function after this one) it can be applied to all the
bodies in oder to make them all move.
21
This function will use several of the lists that are defined at the beginning of the program.
You will need to access the values in each of the lists at only one specific location: that
location is whatever the current body number is.
Do this
Write the moveBody function. It has a single parameter, which is the body number. Note
that the body number is the list index of the body in all the lists Masses, Xs, Ys, etc.
For a body in motion in the cartesian plane, these are the equations:
xnew = x + vx
ynew = y + vy
You can easily calculate xnew and ynew if you know the values of x, y, vx, and vy. Those
values can be found int he corresponding lists Xs, Ys, Vxs, Vys at the right location. Do
you know what that location is? You should know it. It's the value of the parameter
variable.
Calculate xnew and ynew (name these variables appropriately) for the body, and then
update the Xs and Ys list at the same location with the values xnew and ynew (i.e., replace
the values in the Xs and Ys list, but only at the location for this body).
Now you must actually move the body.
Now get the correct turtle out of the Turtles list and put it in a variable because you'll
need to do a few things to it. Do these things to that turtle in this order:
1. Hide the turtle.
2. Change the color to TraceColor.
3. Goto xnew , ynew.
4. Change the color to BodyColor.
5. Show the turtle.
Then add this statement to the bottom of the function:
if xNew < -WinX2 or xNew > WinX2 or yNew < -WinY2 or yNew > WinY2:
OffScreen[n] = True
If you did not name your variables xNew and yNew, then replace those variables in that if
statement with the variables that you did use.
22
Also, in my program I called the parameter n but you may have called it something else. If
you did call it something else, change OffScreen[n] to use whatever your parameter
variable is instead of n.
That whole if statement checks to see if the body has moved off the screen. If it has, it
will set the value in the OffScreen list to True. You'll use OffScreen again later to
determine if all the bodies have moved off the screen.
Change the main function
In the main function, put this for loop just below the setup() function call:
for n in range(100):
moveBody(0)
turtle.update()
That runs a loop 100 times. With each iteration it moves body number 0 and then forces a
display update.
Test it
Run the program. One of the bodies should move in a straight line.
You can comment out the call to printBodies in the setup function. Displaying all that
information to the IDLE screen is so slow.
6.9. Function moveBodies
Summary
This is a rather short function that will call the moveBody function on all the bodies.
23
Do this
Write this function. It has no parameters.
It must iterate over all the bodies. That means you must start a for loop that iterates over
the range NBodies.
In the body of the loop get the value of the Turtles list at that body number location. If
that value is not equal to None, then call the moveBody function on that body number.
for in :
t = one of the turtles
if t is not None:
move the body (not the turtle)
Note that the only reason you need the turtle t is to check to see if it's None. If it is None,
then skip that body. (As the bodies leave the screen the Turtles list will start filling up
with the value None.)
Test it
Change the main function so that instead of calling moveBody(0) it calls moveBodies().
Run it. All the bodies should move in straight lines.
If the bodies do not move like this, do not proceed until you have fixed the problem.
24
6.10. Function calculateForce
Summary
This function calculates the gravitational force on a single body by all the other bodies.
The resultant force will have an X component and a Y component.
The general formula for gravitational force is this:
where G is the universal gravitational constant, M1 and M2 are the masses of the two
bodies, and r is the distance between the two bodies.
Do this
Create a calculateForce function that has two parameters. The parameters are the body
numbers of the two bodies in question. I called my parameters n1 and n2, but body1 and
body2 would also be good parameter names.
Use the Masses list to get the masses of the two bodies. Put them in variables. I suggest m1
and m2.
Get the locations of the two bodies from the Xs and Ys lists and put them in variables. You
can use variables x1, y1, x2, and y2.
Use the Pythagorean theorem to determine the distance r between the bodies. It would be
useful to create two other variables first: dx and dy, where dx is the difference between
the x values and dy is the difference between the y values. (Does it matter if you do x1 -
x2 or x2 - x1? Look how you use dx and dy in the equation below:)
! = #$% + #'%
Converting to Python:
x squared is x ** 2
Square root of x is math.sqrt(x)
Now calculate the force f using this equation:
25
You already have values for G, m1, m2, and r.
In this program the bodies have a simulated mass and they're drawn on the screen with
different sizes, but the sizes of the bodies are not taken into account anywhere, or the fact
that they're supposed to be made of matter and that they can't occupy the same space at
the same time. This oversimplification allows the distance between two bodies to become
arbitrarily small or even 0. What happens to the force as the distance r approaches 0?
We'll ignore that problem for now.
Now that you have the resultant force, you need to decompose it into its x and y
components.
Calculate the angle of the force by calling math.atan2(dy, dx) where dy and dx are the
variables you created previously. Store that in a variable.
The force in the x direction is the total force f times the cosine of the angle.
The force in the y direction is the total force f times the sine of the angle.
Use math.cos and math.sin to calculate the cosine and sine.
I used variable names fx and fy for those values.
Return the two values fx and fy, like this:
return fx, fy
Test it
Add these statements to your main function, just before the very first print statement:
global Masses, Xs, Ys
Masses = [45, 32, 62, 95, 16]
Xs = [-119, -19, 3, -212, -174]
Ys = [-71, 228, -193, 93, -18]
print(calculateForce(0, 1))
Masses = []
Xs = []
Ys = []
26
This sets the Masses, Xs, and Ys lists to known values and prints the force between bodies
0 and 1. Run the program. The first line printed in the Python Shell should be this:
(0.022974515744906363, 0.06869380207727004)
Your answer should be accurate to at least the first few decimal places. If you do not see
the same numbers, then fix the problem. Do not proceed until this part is working.
Then delete those 8 lines that you just added.
6.11. Function accelerateBody
Summary
This function will determine the acceleration of a single body from all the resultant
gravitational forces acting on it from the other bodies. This will cause the body to change
its direction by being drawn toward bodies with a higher mass, and therefore a higher
gravitational pull.
Since force = mass × acceleration, then acceleration = force / mass.
Note that acceleration generally means a change in velocity. Even a negative acceleration
can be called acceleration.
Do this
Add an accelerateBody function with a single parameter: the body number.
To calculate the total force on a body, you must add up all the separate forces on a body
by all bodies other than itself.
Start a for loop that does this:
For each body number in the range NBodies:
If that body number is not equal to the body number parameter:
Calculate the force on the body by calling calculateForce. That
function returns two values. You can capture them in variables like
this:
c, d = calculateForce(a, b)
but don't use those variable names literally. That's just an example of
how to do it.
Calculate the x & y accelerations. Create new variables for this. The x
27
acceleration is the force in the x direction divided by the mass of the
body (the body is the one specified by the body number parameter).
Do the same for the y acceleration.
Add the x & y accelerations to the x and y velocities of the body (You
know where to find those, right?) The body is the one specified by the
body number parameter. And don't just add the accelerations to the
velocities, you must add and then store the sums back into the
respective lists.
Test it
Add the function call accelerateBody(0) the main function just after the
moveBodies() function call:
for n in range(100):
moveBodies()
accelerateBody(0) ← new
turtle.update()
You may have to run the program a few times but eventually you'll see one of the bodies
curve toward the center of mass of the group of bodies.
If the body seems to accelerate away from all the other bodies instead of toward them,
then you have a problem in your program. Do not proceed until you have fixed the
problem.
28
6.12. Function accelerateBodies
Summary
This is a rather short function that will call the accelerateBody function on all the
bodies.
Do this
Write this function. It has no parameters.
This function is very similar to the moveBodies function.
It must iterate over all the bodies. That means you must start a for loop that iterates over
the range NBodies.
In the body of the loop get the value of the Turtles list at that body number location. If
that value is not equal to None, then call the accelerateBody function on that body
number.
for in :
t = one of the turtles
if t is not None:
accelerate the body (not the turtle)
Note that the only reason you need the turtle is to check to see if it's None. If it is None,
then skip that body. (As the bodies leave the screen the Turtles list will start filling up
with the value None.)
Change the main function so that instead of calling accelerateBody(0) it calls
accelerateBodies().
Test it
Sometimes two bodies will get so close that they will accelerate wildly and shoot off the
screen. Other times the bodies will orbit each other and stay on the screen.
29
If the bodies zip off the screen too quickly, you can try reducing MaxVelocity (this
represents the maximum initial velocities of the bodies) or MaxMass.
6.13. Let the animation run longer
Summary
Currently the animation runs for 100 iterations. It would be nice to let it run until all the
bodies have left the screen.
Fortunately that's really easy to do since there's that OffScreen list that you created a
while ago. As each body leaves the screen (meaning, its center leaves the bounds of the
window), its corresponding value in the OffScreen list is set to True. When all the values
in that list are True, then you know that all the bodies are off the screen.
Do this
Change the for loop in the main function to this while loop instead:
while not all(OffScreen):
That's it. The all function in Python checks to see if all the values in a list are True. If so,
then the all function returns True. If any one of the values is False, then the all
function returns False. The not operator inverts that value from True to False or from
False to True.
Test it
Pretty.
30
6.14. Use different numbers
Change NBodies to 10.
Change MaxMass to 10.
Run it.
That might yield a more pleasing animation.
Mess around with the numbers more and see if you can get it to look even better.
Or change the colors.
The original values are these, in case you want to put them back:
NBodies = 5
G = 5
SpaceRadius = 250
MinMass = 5
MaxMass = 100
MaxVelocity = 100
BodyColor = 'black'
TraceColor = 'green'
7. Report
Create a word processor document file. Save the file with the name LastName-HW5 with
a .doc or .docx format. For example, my report would be named Meunier-HW5.docx.
31
At the beginning of the document include this information:
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
Be sure to replace the parts that are underlined above, and choose only one instructor.
Now create the following sections in your document.
1. Introduction
In this section copy & paste the text from the introduction section of this
assignment. (It's not plagiarism if you have permission to copy something. I give
you permission.) You're allowed to rewrite it a little to make it sound better.
2. Output
Run your program and copy & paste the output from the Python Shell window here
(un-comment the call to printBodies first). You do not need to write anything.
Also copy and paste a screen shot or two. Convert your screen shot to JPG format
(preferable) or PNG format (acceptable) before pasting it into your report. Under no
circumstances should you ever paste a BMP file into a document that you send
someone.
3. Source code
Copy & paste the contents of your nbody.py file here. You do not need to write
anything. Please format it nicely using a fixed-width font, but you do not need to
colorize anything.
8. Submission
Submit the following things things on HuskyCT:
1. The nbody.py file.
2. The report document.
If there is no way to submit your assignment on HuskyCT, then please contact your TA. Do
not email your professor.
32
9. Grading Rubric
Your assignment will be graded based on these criteria:
(2 points) The comment block at the beginning of the program file is correct.
(12 points) The program works correctly and contains all the necessary functions.
(3 points) The program is formatted neatly. Follow this style guide if you're not sure:
https://www.python.org/dev/peps/pep-0008/
(3 points) The document contains all the correct information and is formatted
neatly.

http://www.6daixie.com/contents/3/1932.html

因为专业,所以值得信赖。如有需要,请加QQ99515681 或邮箱:[email protected] 

微信:codinghelp

猜你喜欢

转载自www.cnblogs.com/pythonTome/p/9768513.html