3

我正在用 python 创建一个基本的物理引擎,并且我设法创建了一个简单的“行星”类来处理数学。当一颗小行星绕着一颗大行星运行时,我还创建了一个基本的工作场景——如果这个小行星的质量为零。然而,当我给这颗小行星任何质量时,它会慢慢地将太阳拉到右边,形成弧形。在这张图片中更容易看到:

(在这张图片中更容易看到).

我明白发生了什么——地球正在将太阳拉到一边并阻止它,但没有将其拉回另一侧——但我不知道如何解决它,除了给太阳一个硬编码的速度。我检查了其他一些来源,但没有任何帮助 - 事实上,这个物理模拟也有同样的问题(取消选中以系统为中心)。

这会发生在现实世界中,还是这种模拟的故障?无论哪种方式,是否有某种黑客可以防止这种情况发生?

我的星球类(所有方法都非常简单):

import math

G = 6

class Planet():
def __init__(self, x = 0, y = 0, vx = 0, vy = 0, mass = 1, radius = 1, colour = "#ffffff"):
    self.x = x
    self.y = y
    self.vx = vx
    self.vy = vy
    self.mass = mass
    self.radius = radius
    self.colour = colour
def draw(self, canvas):
    canvas.create_oval(self.x - self.radius, self.y - self.radius, self.x + self.radius, self.y + self.radius, fill = self.colour)
def move_next(self):
    self.x += self.vx
    self.y += self.vy
def apply_gravity(self, other):
    if other is self: #make sure you're not checking against yourself.
        return 1
    x = other.x - self.x
    y = other.y - self.y
    r = math.hypot(x, y)
    if r == 0: #make sure they're not on each other.
        return 1
    gravity = G * (other.mass) / (r ** 2) #calculate the force that needs to be applied
    self.vx += (x / r) * gravity #normalise the x component of vector and multiply it by the force
    self.vy += (y / r) * gravity #normalise the y component of vector and multiply it by the force

和“主要”文件:

from tkinter import *
import time

import planet

FPS = 1/60

window = Tk()
canvas = Canvas(window, width = 640, height = 400, bg = "#330033")
canvas.pack()

earth = planet.Planet(x = 320, y = 100, vx = 10, mass = 1, radius = 10, colour = "lightblue") #Because the earth's mass is so low, it won't be AS noticable, but it still pulls the sun a few pixels per rotation.
sun = planet.Planet(x = 320, y = 200, mass = 2e3, radius = 20, colour = "yellow")
planets = [earth, sun]

while True:
    canvas.delete(ALL)
    for planet in planets:
        for other in planets:
            planet.apply_gravity(other)
        planet.move_next()
        planet.draw(canvas)
    window.update()
    time.sleep(FPS)
4

0 回答 0