我正在尝试制作一个使用现实物理学模拟太阳系的pygame应用。当我使用大量数字(例如太阳的质量或地球与太阳的距离)时,会出现此错误:
python filename.py
我尝试使用较小的数字作为质量的比例(太阳是150kg,地球是sun.mass * 0.00000300251),但是如果我添加的行星越多,这将变得非常复杂,并且我不能在距离太阳。我试图将数字用科学计数法表示,但这也会引起问题。
这是我的body.py文件(我删除了所有缩放比例数学以及所有不使用大数的内容)
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/Solar System Simulator/solsyssim.py", line 103, in <module>
run_again = main()
File "C:/Users/User/PycharmProjects/Solar System Simulator/solsyssim.py", line 94, in main
body.draw(screen, zoom, translation)
File "C:\Users\User\PycharmProjects\Solar System Simulator\body.py", line 50, in draw
pygame.draw.circle(screen, self.color, (int(self.x * zoom + translation[0]), int(self.y * zoom + translation[1])), round(self.radius * zoom))
OverflowError: Python int too large to convert to C long
这些是我的main.py文件的片段,这些片段创建了具有大量数字的Body对象。
#body.py
import math
import pygame
G = 6.673 * (10 ** -11)
class Body:
def __init__(self, x, y, bodies, mass=1000, radius=25, color=(255, 255, 0), xv=0, yv=0):
self.x = x
self.y = y
self.xv = xv
self.yv = yv
self.mass = mass
self.radius = radius
self.color = color
self.bodies = bodies
def tick(self):
xf, yf = 0, 0
for body in self.bodies:
if body != self:
v = self.force(body)
xf += (math.cos(v.angle) * v.force) * body_data.force_scale
yf += (math.sin(v.angle) * v.force) * body_data.force_scale
self.xv += xf / self.mass
self.yv += yf / self.mass
self.x += self.xv
self.y += self.yv
def draw(self, screen, zoom, translation):
pygame.draw.circle(screen, self.color, (math.floor(self.x), math.floor(self.y)), math.floor(self.radius))
def dist(self, b):
return math.sqrt(((b.x - self.x)**2) + ((b.y - self.y) ** 2))
def angle(self, b):
return math.atan2(b.y - self.y, b.x - self.x)
def force(self, b):
return Vector2D((G * b.mass * self.mass) / self.dist(b), self.angle(b))
class Vector2D:
def __init__(self, force, angle):
self.force = force
self.angle = angle
和
sun_mass = 1.9891e30
earth_mass = 5.972e24
earth_dist = 149.6 * 10**6
这是我的缩放/平移计算,每隔一个刻度运行一次,并将其传递给body.draw函数:
sun = Body(winsize[0] // 2, winsize[1] // 2, bodies, sun_mass, 25)
earth = Body(sun.x - earth_distance, size[1] // 2, bodies, earth_mass, 10, (0, 0, 255), 0, initial_velocity)
如果数字太大而无法转换为整数,并且pygame.draw.circle需要数字为整数,我不知道如何绘制行星的圆圈。
编辑:谢谢大家的建议并尝试帮助我!我最终按照def get_zoom(bodies):
d = 0
for body in bodies:
d = max(body.y, body.x, d)
print("D:", d, "/", max(size))
return max(size) / (d * 2)
def get_translation(zoom):
return size[0] // 2 - (size[0] // 2 * zoom), size[0] // 2 - (size[1] // 2 * zoom)
的建议进行了操作,但是我在绘制时按比例缩小了所有距离,而没有按比例缩小质量,因此物理仍然是现实的。再次感谢你们提供的所有帮助和故障排除帮助;它确实帮助我了解了有关Python的更多信息!