-
Notifications
You must be signed in to change notification settings - Fork 3
/
newton.py
92 lines (76 loc) · 3.44 KB
/
newton.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
from basic_linalg import *
import matplotlib.pyplot as plt
import math
G = 6.674 * 10 ** (-11)
class Body:
name: str
position: Vector
mass: float
velocity: Vector
diameter: float
color: str
applied_force: Vector
acceleration: Vector
def __init__(self, name: str, position: Vector, mass: float, velocity: Vector, diameter: float, applied_force: Vector, acceleration: Vector):
self.name = name
self.position = position
self.mass = mass
self.velocity = velocity
self.diameter = diameter
self.color = 'black'
self.applied_force = applied_force
self.acceleration = acceleration
def disp(self):
return ('Name: %s, Position: [%f,%f], Velocity: [%f,%f], Mass: %f \n') % (
self.name, self.position[0], self.position[1], self.velocity[0], self.velocity[1], self.mass)
def calculate_force(obj1: Body, obj2: Body) -> Vector:
force_direction = vector_addition(obj2.position, vector_multiplication_by_k(-1.0, obj1.position))
distance = vector_length(force_direction)
total_force = (G * obj1.mass * obj2.mass) / (distance ** 2)
return vector_multiplication_by_k(total_force / distance, force_direction)
class SpaceImage:
bodies: List[Body]
def __init__(self, bodies: List[Body]):
self.bodies = bodies
def next_image(self, jump: int):
new_bodies: List[Body] = []
for obj in self.bodies:
obj.position = vector_addition(obj.position, vector_multiplication_by_k(jump, obj.velocity))
obj.velocity = vector_addition(obj.velocity, vector_multiplication_by_k(jump, obj.acceleration))
new_bodies.append(obj)
self.bodies = new_bodies
new_bodies = []
for obj in self.bodies:
resulting_force = [0.0, 0.0]
for other_obj in self.bodies:
if other_obj.position != obj.position:
resulting_force = vector_addition(resulting_force, calculate_force(obj, other_obj))
obj.applied_force = resulting_force
obj.acceleration = vector_multiplication_by_k(1 / obj.mass, resulting_force)
new_bodies.append(obj)
self.bodies = new_bodies
def add_body(self, body: Body):
self.bodies.append(body)
def show(self):
for body in self.bodies:
plt.scatter(body.position[0], body.position[1], body.diameter/10**5, edgecolors='none')
def save(self, file_name, axis, second):
plt.axis(axis)
plt.gca().set_aspect('equal', adjustable='box')
plt.title('Day: %d, Hour: %d' % (
math.floor(second / 60 / 60 / 24), second / 60 / 60 - math.floor(second / 60 / 60 / 24) * 24))
plt.xlabel('Meters')
plt.ylabel('Meters')
plt.axvline(color='black')
plt.axhline(color='black')
for body in self.bodies:
print(body.disp())
plt.scatter(body.position[0], body.position[1], body.diameter/10**5, edgecolors='none')
if vector_length(body.applied_force) and vector_length(body.velocity):
plt.quiver(body.position[0], body.position[1], body.applied_force[0], body.applied_force[1],
color=['r'], scale=3 * 10 ** 21)
plt.quiver(body.position[0], body.position[1], body.velocity[0], body.velocity[1], color=['b'],
scale=10000)
plt.savefig(file_name, bbox_inches='tight')
plt.clf()
return file_name