私は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)