PythonでCanvas使ってみる(4)うねうねアニメ
(末尾にアニメーションのvimeo動画があります。是非「動画」としてご覧ください)
一週間ほど前
>「アニメーション」はおそらく使いそうもない
などと書いていましたが、前回完成した、スピログラフアプリ
をいじっているうちに、「うねうね」させたくなってきました(笑)
何を言っているかというと、例えば
とパラメータsを「連続的に」振ることで図形が「連続的に」変化していくわけですが、これをアニメーションにしたら面白いんじゃないかな?と思ったわけです。
要は
・ある画面の表示をする。
・連続的な変化がある次の画面表示へ移る
というのを繰り返せばいい。
こういうのこそ、(スピログラフの「定規」だけでは絶対できない)プログラミングならではの優位性じゃないですかね。
UdemyTkinter教材のアニメーションの回では
windowやフレームのafterメソッド(指定時間後に関数呼び出し)に
・after(ミリ秒,呼び出す関数)
についての説明がありました。これを使いましょう。
やってみます
(抜粋)
# うねうね
def mycommand2(self):
# 画面クリア
self.canvas.delete("all")
# 刻み度数
self.ddeg = float(self.ctkentry_刻み.get())
# 外側の歯数
self.gearl = int(self.ctkentry_外歯車.get())
# 内側の歯数
self.gears = int(self.ctkentry_内歯車.get())
# うねる回数
self.unekaisu = int(self.ctkentry_うねる回数.get())
# アニメ描画
self.sratio = 0
self.unediff = 0.01
self.spiro_ani()
def spiro_ani(self):
if self.unekaisu > 0:
if ((self.sratio < 1.0) and (self.unediff > 0)) or (
(self.sratio > 0.0) and (self.unediff < 0)
):
self.spiro(self.ddeg, self.gearl, self.gears, self.sratio)
self.sratio += self.unediff
self.after(10, self.spiro_ani)
else:
self.unediff *= -1.0
self.unekaisu -= 1
self.spiro_ani() # 再帰呼び出し
# spiro一枚描き上げ
def spiro(self, ddeg, gearl, gears, sratio):
# 画面クリア
self.canvas.delete("all")
# ギア比
r = gears / gearl
# ぶん回す回数
w = math.lcm(gearl, gears) / gearl
s = r * sratio
for deg in np.arange(0, 360 * w, ddeg):
self.penline(deg, ddeg, r, s)
# 内接円の中心位置 thetaはラジアン
def circle_s_center(self, theta, r):
return (1 - r) * math.cos(theta), (1 - r) * math.sin(theta)
# 内接円の中心から見たペン先位置
def rel_pen(self, theta, r, s):
return s * math.cos(-theta * (1.0 / r - 1)), s * math.sin(
-theta * (1.0 / r - 1)
)
def abs_pen(self, theta, r, s):
cx, cy = self.circle_s_center(theta, r)
rpx, rpy = self.rel_pen(theta, r, s)
return cx + rpx, cy + rpy
def penline(self, deg, ddeg, r, s):
theta_rad1 = math.radians(deg)
theta_rad2 = math.radians(deg + ddeg)
x1, y1 = self.abs_pen(theta_rad1, r, s)
x2, y2 = self.abs_pen(theta_rad2, r, s)
self.canvas.create_line(
self.tfm.transform(x1, y1),
self.tfm.transform(x2, y2),
fill="white",
width=1,
)
こんな感じに書いてmycommand2 を実行したら・・
(Vimeoの動画です是非「動かして」ご覧ください)
うねってます(笑)
動きがあると俄然面白くなりますね。
この記事が気に入ったらサポートをしてみませんか?