太陽系シミュレーターを作成する

まえがき

新しいものへの永遠の渇望は、Pythonのような素晴らしいプログラミング言語の研究を推し進めました。 よくあるように、アイデアの欠如は、その実装はあなたの時間を費やすのが残念ではありませんが、プロセスを大きく阻害しました。



運命の意志により、Pythonでのプラットフォームゲームの作成に関する素晴らしいシリーズの記事が目に飛び込んできました。

ここここ

私は1つの古いプロジェクトを引き受けることにしました。 重力の影響下での体の動きをシミュレートします。



これから来たものは読み続けた。



パート1 理論的



問題を解決するには、まずそれを明確に想像する必要があります。

フックまたは詐欺師によって、私たちはなんとかその中に身体のある空気のない空間の二次元断面を得ることができたと仮定します。 すべての体は重力の影響下で動きます。 外部への影響はありません。

互いの動きのプロセスを構築する必要があります。 実装の容易さと最終結果のカラフルさは、インセンティブと報酬として役立ちます。 Pythonをマスターすることは、将来的には良い投資になるでしょう。



座標系を紹介します。



私たちのシステムが2つの本体で構成されているとします。

1.質量Mと中心(x0、y0)の大質量星

2.ポイント(x、y)、速度v =(vx、vy)および加速度a =(ax、ay)を中心とする質量mの光惑星。



このケースを整理できれば、星と惑星が相互に影響しあう複雑なシステムに簡単に移行できます。 次に、最も簡単な方法について説明します。



ニュートンの2番目の法則である重力の法則と同様の三角形を簡単に操作した後、次のことがわかりました。



ax = G * M *(x0-x)/ r ^ 3

ay = G * M *(y0-y)/ r ^ 3



これにより、星の重力場で惑星を動かすためのアルゴリズムを作成できます。



1.開始する前に、惑星の初期位置(x、y)と初期速度(vx、vy)を設定します

2.各ステップで、上記の式に従って新しい加速度を計算し、その後、速度と座標を再計算します。



vx:= vx + T * ax

vy:= vy + T * ax



x:= x + T * vx

y:= y + T * yx



定数GとTを処理するために残ります。G= 1を置きます。私たちの問題にとって、これはそれほど重要ではありません。 パラメータTは、計算の精度と速度に影響します。 また、1を入力して開始します。



パート2 実用的



だから、私の最初のPythonプログラム。 同時に、実践的な指導をしてくれたVeleseに改めて感謝したい。



import pygame, math from pygame import * from math import * WIN_WIDTH = 800 WIN_HEIGHT = 640 PLANET_WIDTH = 20 PLANET_HEIGHT = 20 DISPLAY = (WIN_WIDTH, WIN_HEIGHT) SPACE_COLOR = "#000022" SUN_COLOR = "yellow" PLANET_COLOR = "blue" #Sun position X0 = WIN_WIDTH // 2 Y0 = WIN_HEIGHT // 2 #Sun mass M0 = 5000 #Stop conditions CRASH_DIST = 10 OUT_DIST = 1000 def main(): #PyGame init pygame.init() screen = pygame.display.set_mode(DISPLAY) pygame.display.set_caption("Solar Mechanics v0.1") #Space init bg = Surface((WIN_WIDTH,WIN_HEIGHT)) bg.fill(Color(SPACE_COLOR)) draw.circle (bg, Color(SUN_COLOR), (X0, Y0), 10) #Timer init timer = pygame.time.Clock() #Planet init planet = Surface((PLANET_WIDTH, PLANET_HEIGHT)) planet.fill(Color(SPACE_COLOR)) draw.circle (planet, Color(PLANET_COLOR), (PLANET_WIDTH // 2, PLANET_HEIGHT // 2), 5) #Planet to Sun distance r = 0.0 #Initial planet pos, speed and accel x = 100.0 y = 290.0 vx = 0.1 vy = 1.5 ax = 0.0 ay = 0.0 done = False while not done: timer.tick(50) for e in pygame.event.get(): if e.type == QUIT: done = True break r = sqrt((x - X0)**2 + (y - Y0)**2) ax = M0 * (X0 - x) / r**3 ay = M0 * (Y0 - y) / r**3 #New spped based on accel vx += ax vy += ay #New pos based on speed x += vx y += vy screen.blit(bg, (0, 0)) screen.blit(planet, (int(x), int(y))) pygame.display.update() if r < CRASH_DIST: done = True print("Crashed") break if r > OUT_DIST: done = True print("Out of system") break #Farewell print (":-)") if __name__ == "__main__": main()
      
      







これは、ある程度のシミュレーション後のシステムの外観です







このメモが書かれている間、シミュレーターは新しい機能に成長しました:スターシステム内のオブジェクトの数は制限されず、相互の影響は考慮され、計算部分はそのクラスに移動され、システム構成は別のファイルに設定され、システムを選択する機能が追加されます。



現在、興味深いシステムシナリオと小さなインターフェイスの改善を探しています。



現在開発中の例を次に示します。





このメモが好意的なレビューを満たしている場合、新しいバージョンの話を続けることを約束します。



更新:



1.すべての評論家の批判に感謝します。 彼らは素晴らしい食べ物を提供します。



2.プロジェクトは成長しました。 すべての物体はすでに独立しており、万有引力の法則に従って互いに影響を及ぼし、N ^ 2の相互作用が計算されます。

これで、外部ファイルにスターシステム構成を保存し、開始時に選択することが可能になりました

ここにコード

次のように実行します:python3.3 main.py -f <configuration name> .ini

さまざまな構成が同じ場所にあります。



3.コメントのおかげで、座標の計算方法である主要な欠陥を見つけて排除することができました。

現在、ルンゲクッタ法が使用されています。 「非厳しいタスク」を読みながら、新しい方法を学びます。



All Articles