处理大量的空间物理学

时间:2019-06-25 16:52:57

标签: python windows pygame game-physics python-3.7

我正在尝试制作一个使用现实物理学模拟太阳系的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的更多信息!

0 个答案:

没有答案