-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAsteroid.py
100 lines (85 loc) · 4.28 KB
/
Asteroid.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from Planet import Planet
import random as rand
import numpy as np
from Solar import Solar
class Asteroid():
def __init__(self):
self.sim = Solar('solardata.csv')
self.numberOfAsteroids = 0
self.log = 'asteroidExperimentLog.txt'
# This function runs the simulation for a given number of years - a probability is required as a float between
# 0 - 1. representing a percentage. i.e 0.1 is 10%
def runAsteroidSimulation(self, years, probability):
self.logString("New Experiment Started for " + str(years) + " Years!")
earth = self.sim.getPlanet('Earth')
time = years * self.sim.calculateOrbitalPeriods(earth)
while self.sim.time < time:
self.sim.runTimestep()
# if the random number generated is less than the probability - then add an asteroid
if rand.random() < probability:
self.addAsteroid()
# check if there is a close encounter and then log it
for obj in self.sim.planets:
if obj.name == 'asteroid':
if self.closeEncounter(obj):
self.logCloseEncouter(obj)
# this method logs a close encounter to a log file.
def logCloseEncouter(self, asteroid):
with open(self.log, 'a') as myFile:
earth = self.sim.getPlanet('Earth')
distance = self.sim.calculateDistance(earth, asteroid)
myFile.write("There was a close encouter with an asteroid at time: " + str(self.sim.time) +
" and the asteroid had a mass of " + str(asteroid.mass)+ ". The asteroid was " +
str(distance) + "m from earth" + '\n')
# If an asteroid is created, then it is also logged.
def logAsteroid(self, asteroid):
with open(self.log, 'a') as myFile:
myFile.write("An asteroid was randomly created with a position of " + str(asteroid.position) +
" and a velocity of " + str(asteroid.velocity) + ". There are now " +
str(self.numberOfAsteroids) + '\n')
# generic function for logging a string
def logString(self, string):
with open(self.log, 'a') as myFile:
myFile.write(string + '\n')
# This function checks if the asteroid is near the earth -- i.e. will there be an impact
def closeEncounter(self, asteroid):
encounter = False
earth = self.sim.getPlanet('Earth')
distance = self.sim.calculateDistance(asteroid, earth)
# a closest approach is considered around between 10 - 100 thousand km
# had to increase the distance so that we can log how far away it is.
if distance < 100*(10**8):
encounter = True
return encounter
# This function will generate a random position for an asteroid that is reasonable.
# i.e. not too close to the sun and not miles away
def getRandomPosition(self):
# generate an integer value that is the maximum value the asteroid can spawn
max_range = int(self.sim.getAnimationRange())
rand_x = rand.randrange(-max_range,max_range, 1)
rand_y = rand.randrange(-max_range,max_range, 1)
random_position = np.array([rand_x, rand_y])
return random_position
# This function will generate a random velocity for an asteroid -- also within a certain range.
def getRandomVelocity(self):
max_velocity = 50000
vel_x = rand.randrange(-max_velocity, max_velocity, 1)
vel_y = rand.randrange(-max_velocity, max_velocity, 1)
velocity = np.array([vel_x, vel_y])
return velocity
# This function adds an asteroid randomly to the simulation with random velocity and position
def addAsteroid(self):
self.numberOfAsteroids += 1
# asteroids typically weigh between 2.8-3.2 *10^21 kg
asteroid_mass = rand.randrange(280, 320, 1) * 10**19
asteroid_position = self.getRandomPosition()
asteroid_velocity = self.getRandomVelocity()
grey = (0.5, 0.5, 0.5)
asteroid_radius = 10000
asteroid = Planet('asteroid', asteroid_mass, asteroid_position, asteroid_velocity, asteroid_radius, grey)
self.logAsteroid(asteroid)
self.sim.planets.append(asteroid)
def __main__():
i = Asteroid()
i.runAsteroidSimulation(4, 0.1)
__main__()