レベル6. 「巻きずし」アニメの3D化(その2:表面)

# makizushi-07-save.py     2023.04.06 by Kero
# 最終目標「巻きずしを作る3Dアニメ」の保存化版です。

# 7.「巻きずし」アニメの3D化(その2:表面)(makizushi-07.py)の発展版。
# 'ax.plot_surface()' を使って表面表示をします。
# 巻きずしの幅は、z=0からz=10の10です。
# 前回のソースコードの解説(コメント文)を消し、今回の解説をします。

import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
from mpl_toolkits.mplot3d import Axes3D

pi = np.pi

imgs = []

# らせんの計算
maki = 4
r0 = 1
a = 2
kaku0 = 2 * pi * r0 / a
ara = 72
pon = maki * ara + 1
kaku = np.linspace(0, 2 * pi * maki, pon)
kakut = kaku + kaku0
r = a * kakut / (2 * pi)

x = r * np.cos(kakut)
y = r * np.sin(kakut)

# z座標を追加。「表面表示」は前回の「輪郭線」と大きく異なります。
z = np.array([0, 10]) # 今回、z値は0と10の2つのみです。それを配列にします。
z0 = np.tile(z,(pon+1,1)) # その配列をpon+1個用意。最後の1は列生成の呪文。
# これで[[0,10],[0,10],・・・,[0,10]]という配列ができます。

# グラフ化

fig = plt.figure(figsize=(20,10)) # 画像を拡大。
ax = fig.add_subplot(111,projection='3d')
ax.set_box_aspect((6,1,2)) # 軸の長さをx:y:z = 6:1:2に設定。
ax.grid()
ax.view_init(elev=30, azim=-270) # 視点の開始位置をデフォルトから変更。
ax.set_xlim(-5,140) 
ax.set_ylim(-2,20) # 軸の長さに応じてy目盛を変えることができました。
ax.set_zlim(-5,15)
ax.scatter(0,0,0, c='r')

sld = 0

for i in range(1,pon+1):
    rkak = -kakut[i-1] - pi/2
    xr = x[:i] * np.cos(rkak) - y[:i] * np.sin(rkak)
    yr = x[:i] * np.sin(rkak) + y[:i] * np.cos(rkak)
    xr0 = xr - xr[i-1]
    yr0 = yr - yr[i-1]
    sld += np.sqrt(xr0[i-2]**2 + yr0[i-2]**2)
    xr0 = xr0 + sld
    
    xr0 = np.append(xr0, 130) # 終端を130に変更。
    yr0 = np.append(yr0, 0)
    zr0 = z0[0:i+1] # 配列z0の要素は[0,10],[0,10],・・・です。
    xr1 = np.reshape(xr0,(i+1,1)) # reshape でxr0の1次元配列を要素数1個のi+1次元配列にします。 
    yr1 = np.reshape(yr0,(i+1,1)) # 同上。こうしないと、plot_surfaceが動きません。
#     zr1 = z1[0:i+1]            以下不要。
#     xrt = np.append(xr0,xr1)      |
#     yrt = np.append(yr0,yr1)      |
#     zrt = np.append(zr0,zr1)      |
#     xrt = np.append(xrt,xr0[0])   |
#     yrt = np.append(yrt,yr0[0])   |
#     zrt = np.append(zrt,zr0[0])   V

    img = [ax.plot_surface(xr1,yr1,zr0, color='gold')] # [ ]でリストオブジェクト生成。
    imgs.append(img)
    
anime = ArtistAnimation(fig, imgs, interval=1, repeat=True) # 1ミリ秒間隔に変更。
anime.save('makizushi-07-save.gif', writer='pillow') # ファイルに保存。

plt.show()
plt.close()

sys.exit()


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です