フルカラーLEDテープで色の遷移パターンについてまとめてPythonでシミュレーションしてみました.これらは基本的に動画のシーン遷移のものと同じです.
Jupyter notebook としても公開しているので,こちらもご参照ください.
事前準備
今回は赤系のグラデーションパターンから緑系のグラデーションへの遷移を考えていきます.図のようにLEDは5個で左から右に向かって0–4のIDが振られています.
import numpy as np num_pixel = 5 color_start = [np.array((x / (num_pixel - 1), 0, 0)) for x in range(num_pixel)] color_goal = [ np.array((0, x / (num_pixel - 1), 0.5)) for x in range(num_pixel) ]
プロット用に次の関数も準備しておきます.
import matplotlib.pyplot as plt import matplotlib.patches as patch def plot_strip(colors:list, ax:plt.Axes=None): if ax is None: ax = plt.gca() for i in range(len(colors)): circ = patch.Circle(xy=(i, 0), radius=0.4, ec='#A0A0A0', fc=colors[i]) ax.add_patch(circ) ax.set_aspect('equal') ax.set_xlim([-0.5 ,len(colors) - 1 + 0.5]) ax.set_ylim([-0.5,0.5]) ax.axes.yaxis.set_ticks([])
Dissolve
Dissolveは各LEDの色が連続的に変化する遷移です.いわゆる,色の補間をしながら変化していきます.下の例では単純なRGB空間での補間ですが色の補間方法だけでもひとテーマ立つぐらいの奥深い話だったりします.
num_seq = num_pixel c = [(0, 0, 0)] * num_pixel fig,ax = plt.subplots( nrows = num_seq + 1, figsize = (600/72, 600/72), tight_layout = True) for seq in range(num_seq + 1): for i in range(num_pixel): w = seq / (num_seq) c[i] = w * (color_goal[i] - color_start[i]) + color_start[i] plot_strip(c, ax[seq]) ax[seq].set_ylabel(f'{seq}') if seq == 0: ax[seq].set_title('dissolve')
Wipe
Wipeは「拭き取る」という単語の意味通り,端から色を拭き取って下の色が現れてくるような遷移になります.色を順次入れ替えれていくだけなので,アルゴリズムも単純です.
num_seq = num_pixel + 1 c = [(0, 0, 0)] * num_pixel fig,ax = plt.subplots( nrows = num_seq, figsize=(600/72,600/72), tight_layout=True) for seq in range(0, num_seq): for i in range(num_pixel): if seq - 1 < i: c[i] = color_start[i] else: c[i] = color_goal[i] plot_strip(c,ax[seq]) ax[seq].set_ylabel(f'{seq}') if seq == 0: ax[seq].set_title('wipe')
Slide
Slideは名前の通り新しい色を左からスライドさせて差し込んでいくような遷移です.紙芝居に近いです.
num_seq = num_pixel c = [(0, 0, 0)] * num_pixel fig,ax = plt.subplots( nrows = num_seq + 1, figsize = (600/72,600/72), tight_layout = True) for seq in range(num_seq + 1): head = seq - 1 tail = head-num_pixel + 1 for i in range(num_pixel): if head < i: c[i] = color_start[i] else: c[i] = color_goal[num_pixel-(head-i)-1] plot_strip(c,ax[seq]) ax[seq].set_ylabel(f'{seq}') if seq == 0: ax[seq].set_title('slide')
Dissolving Wipe
wipeでは色を置き換えていましたが,これをdissolveで徐々に色を変わるようにしたものです.下の例では2ステップでDissolveが完了します.
num_dis = 2 num_seq = num_pixel + num_dis c = [(0, 0, 0)] * num_pixel fig,ax = plt.subplots( nrows = num_seq, figsize = (600/72,600/72), tight_layout = True) for seq in range(num_seq): for i in range(num_pixel): if seq - 1 < i: c[i] = color_start[i] else: k = (seq - 1) - i + 1 w = k / num_dis if w >= 1.0: c[i] = color_goal[i] else: c[i] = (w * (color_goal[i] - color_start[i]) + color_start[i]) plot_strip(c, ax[seq]) ax[seq].set_ylabel(f'{seq}') if seq == 0: ax[seq].set_title('disolve and wipe')
Dissolving Slide
Slideでは色を置き換えていたものをdissolveで徐々に色が変わるようにしたものです.下の例では2ステップでDissolveが完了します.
num_dis = 2 # num. of steps for disolving num_seq = num_pixel + num_dis c = [(0, 0, 0)] * num_pixel fig,ax = plt.subplots( nrows = num_seq, figsize = (600/72, 600/72), tight_layout = True) for seq in range(num_seq): for i in range(num_pixel): head_dis = seq - 1 head = head_dis - num_dis + 1 tail = head - num_pixel + 1 if head_dis < i: c[i] = color_start[i] elif i <= head: c[i] = color_goal[num_pixel - (head -i) - 1] else: k = num_dis - (head - i) - 2 w = k / num_dis # w = 0.0--1.0 if w >= 1.0: # c[i]=color_goal[num_pixel-seq+i] c[i] = color_goal[-1] else: c[i] = (w * (color_goal[-1] - color_start[i]) + color_start[i]) plot_strip(c, ax[seq]) ax[seq].set_ylabel(f'{seq}') if seq == 0: ax[seq].set_title('slide with dissolving head')
コメント