Pythonを使って宇宙に行きたい③

エフ
2026-03-17
2026-03-17

uchuryokou_family

前回

前回、作成したPythonプログラムが以下になります。

-------------------------------------------
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

fig, ax = plt.subplots()
fig.set_size_inches(5, 5)
ax.set_aspect('equal')
ax.axis('off')

circle = plt.Circle((0.5, 0.5), 0.4, edgecolor='blue', facecolor='none', linewidth=1)
ax.add_patch(circle)

ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

line, = ax.plot([0.5, 0.5], [0.6, 0.6], color='red', linewidth=2)
dot, = ax.plot([0.5], [0.6], 'ro')

# アルファ値(透明度)を徐々に減らす
alpha_values = np.linspace(1, 0, 50)


def update(num):
    if num < 50:
        new_y = 0.6 + num * 0.0075
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([0.5], [new_y])
    else:
        angle = (num - 50) * 0.04 + np.pi / 2 # 角度の調整
        x = 0.5 + 0.475 * np.cos(angle)
        y = 0.5 + 0.475 * np.sin(angle)
        dot.set_data([x], [y])  # dot を再利用
    return line, dot

ani = animation.FuncAnimation(fig, update, frames=200, interval=100, blit=True)
ani.save("line_extending_with_fadeout.gif", writer='pillow')
-------------------------------------------

そして、できたのがこれ。

e-1
軌道がおかしすぎるので、自然な感じに調整したい。(今回)


ポイントは以下

--------------------------------------------------
    if num < 50:
        new_y = 0.6 + num * 0.0075
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([0.5], [new_y])
--------------------------------------------------

50フレームまでまっすぐy軸だけ増加してからの円軌道は不自然。
ということで、30 <= num < 50フレームまでに右上に伸びる軌道に変更。

    if num < 30:
        # 垂直に伸びる
        new_y = 0.6 + num * 0.0075
        line.set_xdata([0.5, 0.5])
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([0.5], [new_y])
    elif 30 <= num < 50:
        # 右上に斜めに伸びる
        new_y = 0.8225 + (num - 30) * 0.0075
        new_x = 0.5 - (num - 30) * 0.0075
        line.set_xdata([0.5, new_x])
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([new_x], [new_y])

かつ、円軌道のスタート地点を90度の場所から135度へ変更

angle = (num - 50) * 0.04 + np.pi * 3 / 4

30
うーん。少しづつ調整すればいい感じになるかもしれないが
もっと美しい方法がある気がする。
フレームごとに少しづつ調整するよりもフレームが増えるごとに
弧を描くようにx軸方向に調整が入る感じにできないか。

20フレームまではy軸方向に直進し、20フレームから
x軸方向には徐々に加速していくように
逆にy軸方向には徐々に減速していくように調整し、
最終地点を円軌道のスタート地点になるに調整。

まずこの円の中心の座標が(0.5, 0.5)で、20フレームy軸方向に進んだ地点が(0.5, 0.75)
赤い点の円軌道の135度の地点の座標が(0.1641, 0.8359)

ということで、
y軸方向は0.75の地点が最速で、0.8359の地点で速度が0になるように
x軸方向は0.5の速度が0で、0.1641の地点が最速になる2次関数で計算する


y軸方向は1フレームに付き、0.00015ずつ減速する
x軸方向は1フレームに付き、0.0004ずつ加速する


ついでに軌道の赤い線がおかしく、これを思い通りにするのは難しいため、
フレーム25で消えるように調整。

そして完成のPythonが以下

-------------------------------------------
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

# Set up the figure and axis
fig, ax = plt.subplots()
fig.set_size_inches(5, 5)
ax.set_aspect('equal')
ax.axis('off')

# Draw a circle
circle = plt.Circle((0.5, 0.5), 0.2, edgecolor='blue', facecolor='none', linewidth=2)
ax.add_patch(circle)

# Set axis limits
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

# Initialize line and dot
line, = ax.plot([0.5, 0.5], [0.6, 0.6], color='red', linewidth=1)
dot, = ax.plot([0.5], [0.6], 'ro')

# Alpha values for fading effect (fade out by frame 25)
alpha_values = np.concatenate([np.linspace(1, 0, 25), np.zeros(175)])

def update(num):
    if num < 20:
        # Vertical extension
        new_y = 0.6 + num * 0.0075
        line.set_xdata([0.5, 0.5])
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([0.5], [new_y])
    elif 20 <= num < 50:
        # Diagonal extension with smoother transition
        t = num - 21
        new_y = 0.75 + t * (0.0075 - 0.00015 * t)
        new_x = 0.5 - t * t * 0.0004
        line.set_xdata([0.5, new_x])
        line.set_ydata([0.6, new_y])
        line.set_alpha(alpha_values[num])
        dot.set_data([new_x], [new_y])
    else:
        # Circular motion
        angle = (num - 50) * 0.04 + np.pi * 3 / 4
        x = 0.5 + 0.475 * np.cos(angle)
        y = 0.5 + 0.475 * np.sin(angle)
        line.set_alpha(0)
        dot.set_data([x], [y])
    return line, dot

# Create animation
ani = animation.FuncAnimation(fig, update, frames=200, interval=100, blit=True)

# Save animation
ani.save("line_extending_with_fadeout.gif", writer='pillow')
-------------------------------------------


肝心のgifが以下

35
うーん。まあまあ。最初よりはましかあ。ちょっと加速度が気に入らない。
まあ、これ以上微調整してもなあ。
本当は重力加速度を計算して、第二宇宙速度とかも計算して
地球の半径も縮尺して、自転も考慮して、正しい速度と平静軌道を計算したい!
もっと言うと、地球衛星軌道に侵入して、スイングバイ軌道とかも計算で出したい!
本当はそういうこともすべて考慮に入れた感じのものをAIに作ってほしかったんだけどなあ。

まあ、2次元平面では無理があるし、今回はこれ以上やっても意味もない気がするので、
これで終了にします。