调用pygame库绘图,通过万有引力公式、矢量运算等等,实现模拟天体,不模拟碰撞。数据有点随便,模拟出来效果并不好。

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
import pygame, sys, random, math, time
pygame.init()
size = width, height = 1440, 900
screen = pygame.display.set_mode(size)
pygame.display.set_caption('天体模拟')
starArr = []
G = 0.009
dt = 0.8
T = time.time()

class star:
def __init__(self, id, sx, sy, m, vx = 0, vy = 0, color = (255, 255, 255)):
self.id, self.m, self.sx, self.sy, self.p, self.color = id, m, sx, sy, [], color
self.vx, self.vy = vx, vy
self.r = math.ceil(m**0.40)
if self.r < 2:
self.r = 2
if self.r > 14:
self.r = 14

# m 100~600
starArr.append(star(id = 0, sx = 720, sy = 450, m = 10000, color = (250,20,60))) # 太阳

starArr.append(star(id = 1, sx = 720, sy = 225, vx = -(G*10000/225)**0.5, m = 50, color = (65,105,225))) # 地球
starArr.append(star(id = 2, sx = 720, sy = 220, vx = -(G*10)**0.5, vy = 0.1, m = 5, color = (210, 220, 230))) # 月球

starArr.append(star(id = 3, sx = 720, sy = 112, vx = -(G*10000/338)**0.5, vy = 0.1, m = 100, color = (205,133,63))) # 木星
starArr.append(star(id = 6, sx = 710, sy = 109, vx = -(G*100/2.24)**0.5, vy = 0.09, m = 1, color = (255,218,185))) # 木卫1
starArr.append(star(id = 7, sx = 730, sy = 119, vx = -(G*100/2.24)**0.5, vy = -0.009, m = 1, color = (255,215,0))) # 木卫2
starArr.append(star(id = 8, sx = 717, sy = 104, vx = -(G*100/2.24)**0.5, m = 1, color = (0,206,209))) # 木卫3

starArr.append(star(id = 4, sx = 720, sy = 562, vx = -(G*10000/112)**0.5, m = 7, color = (100,149,237))) # 水星

starArr.append(star(id = 5, sx = 720, sy = 750, vx = (G*10000/300)**0.5, m = 48, color = (225,69,0))) # 火星

def drawStar():
for star in starArr:
pygame.draw.circle(
screen,
star.color,
(star.sx, star.sy),
star.r,
0
)

def main():
screen.fill((0, 0, 0))
# 随机流星
global T
if time.time() - T > 1 and len(starArr) < 30:
tmp_v = random.random() + 0.5
starArr.append(
star(
id = len(starArr),
sx = width - random.randint(0, 20),
sy = random.randint(0, 20),
m = 2,
vx = -tmp_v + (random.random() * 0.15),
vy = tmp_v + (random.random() * 0.15)
)
)
T = time.time()
for starA in starArr:
fx, fy = 0, 0
for starB in starArr:
if starA.id == starB.id:
continue
# startA为自身 下面计算AB距离l 和单位向量 u
Dx, Dy = starB.sx - starA.sx, starB.sy - starA.sy
l = ( (Dx)**2 + (Dy)**2 ) ** 0.5
limitR = starA.r + starB.r
if l < limitR:
l = limitR
u = Dx / l, Dy / l
F = G * starA.m * starB.m / (l**2) # 万有引力公式
u = u[0]*F, u[1]*F # F合 = u*F
fx += u[0]
fy += u[1]
# 合力累加完毕
ax = fx / starA.m
ay = fy / starA.m
starA.vx += ax * dt
starA.vy += ay * dt
starA.sx += starA.vx * dt
starA.sy += starA.vy * dt
if abs(starA.sx) > width + starA.r or abs(starA.sy) > height + starA.r:
starArr.remove(starA)
drawStar()

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
main()
pygame.display.update()
time.sleep(0.001)
pygame.quit() # 退出pygame