联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> Python编程Python编程

日期:2018-10-09 10:09

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.


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp