2023.02.13
アフィン変換でらせんを描く動画です。原点から「吹き出し」のように広がり、パチンとはじけてまたゼロから始まります。例によって動画とPython ソースコードを表示します。(Python開発環境でお試しください。)
# CS-1 螺旋部分2次元アニメ基礎検討その2 2023.02.13 by Kero
# 今回は、行列演算(アフィン変換)を利用して、「吹き出し」風にした。
# 回転角に比例してらせん中心からの距離が長くなる「等差らせん」を作る。
# 接線の傾きをらせんの回転角とする。
# 各i点における傾きは点i-1から点iへの傾きとする。
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
# 描画画面設定。
fig, ax = plt.subplots()
ax.set_aspect('equal') # 正方形の方眼紙。
artists = [] # パラパラ漫画設定。最初は白紙。
# 回転のマトリックス設定。座標の列ベクトル群に左から掛けると回転。
def A(rd):
Am = np.array([[np.cos(rd), -np.sin(rd), 0],
[np.sin(rd), np.cos(rd), 0],
[0., 0., 1.]])
return Am
# 各点の回転角度を予め計算しておく。【重要】
# 右端(x=100)の点は、x=99を中心にπ/2(=1.570)回転。
do = [0] * 101 # for文でiは100から1までだけど、なぜか101個必要。
ri = 0
for i in range(100, 0, -1):
do[i] = np.pi/2 - np.arctan2(ri, 1.)
ri = np.sqrt(np.square(ri) + 1.)
dp = np.array(do)
sf = np.array([[1],[0],[0]]) # 図形を右に1移動するため。
ad = np.array([[0],[0],[1]]) # 図形に点(0,0)を追加するため。
# 図形(座標の列ベクトル)の最初は原点。
zu = np.array([[0],[0],[1]])
# ここかららせん作成。
for i in range(100, 0,-1):
zu = zu + sf # 図形を右に1移動。
zu = np.append(zu, ad, axis=1) # 図形に原点を追加。
Am = A(dp[i]) # 図形の回転マトリックスを作る。
zu = np.dot(Am, zu) # かいてーん!!
artist= ax.plot(zu[0], zu[1], c='b') # グラフ表示。
artists.append(artist) # 一コマをパラパラ漫画の1ページに収録。
anim = ArtistAnimation(fig, artists, interval=100, repeat=True)
anim.save('rasen-230213.gif', writer='pillow')
plt.show()
plt.close()