
-------------------------------------------
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')
-------------------------------------------
そして、できたのがこれ。

軌道がおかしすぎるので、自然な感じに調整したい。(今回)
ポイントは以下
--------------------------------------------------
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

うーん。少しづつ調整すればいい感じになるかもしれないが
もっと美しい方法がある気がする。
フレームごとに少しづつ調整するよりもフレームが増えるごとに
弧を描くように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が以下

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

