Я пытаюсь создать приложение для пигмеев, которое использует реалистичную физику для моделирования солнечной системы.Когда я использую большие числа, такие как масса Солнца или расстояние от Земли до Солнца, я получаю эту ошибку:
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
Я пытался использовать меньшие числа, которые являются отношениями масс (Солнце составляет 150 кг иЗемля - это солнце. Mass * 0.00000300251), но чем больше планет я добавляю, тем сложнее становится это, и я не могу сделать это на расстоянии от Солнца.Я попытался поместить числа в научную нотацию, но это также вызывает проблемы.
Это мой файл body.py (я удалил все математические вычисления и все, что не использовало большие числа)
#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
Это фрагменты моего файла main.py, который создает объекты Body с большими числами.
sun_mass = 1.9891e30
earth_mass = 5.972e24
earth_dist = 149.6 * 10**6
и
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)
Вот мое масштабирование / переводвычисление, которое выполняется каждый тик и передается в функцию body.draw:
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)
Я не знаю, как нарисовать круги для планет, если числа слишком велики для преобразования в целые числаи pygame.draw.circle нужно, чтобы числа были целыми числами.
РЕДАКТИРОВАТЬ: Спасибо всем за предложения и пытаясь помочь мне!Я закончил тем, что сделал то, что предложил pault
, но я уменьшил все расстояния при рисовании, не уменьшая массы, чтобы физика все еще была реалистичной.Еще раз спасибо вам, ребята, за всю помощь и помощь в устранении неполадок;это действительно помогло мне узнать больше о Python!