見出し画像

【うなり】 変位のアニメーション描画と解説


この記事で伝えたい事

・うなりのアニメーションを見て楽しんで下さい ^^
・「周波数ジェネレーター」というアプリでうなりの実験が無料で可能です

※ アプリは自分が作ったものではありません


概要

少し調べてみたが目についた解説は静止画ベースだったので、pythonで描画したgifも交えて、「うなり」について解説する。

うなりとは

周波数の近い波を同時に聴くと音の大きさが周期的に大きくなったり小さくなったりして聴こえるという現象が存在する。(下の方に記載してあるが、スマホ一つで無料で体験できる。)

波の重ね合わせをした波の式

波の重ね合わせは下記のように三角関数和積の公式を用いて計算される。

$$
y(x,t)=\sin\Bigr(2 \pi \bigl( \frac{x} {\lambda_1} - f_1 t \bigr) \Bigr) + \sin \Bigl( 2 \pi \bigl( \frac{x} {\lambda_2} - f_2 t \bigr) \Bigr)\\ \ \\
=2\sin \Bigl(\pi \bigl( \frac{x} {\lambda_1} + \frac{x} {\lambda_2 } - f_1 t -f_2 t\bigr) \Bigr) \cos \Bigl(\pi \bigl( \frac{x} {\lambda_1} - \frac{x} {\lambda_2 } - f_1 t + f_2 t\bigr) \Bigr) \\ \ \\
=2\sin \Bigg(\pi \Bigl(x( \frac{1} {\lambda_1} + \frac{1} {\lambda_2 } )- (f_1 + f_2) t\Big) \Bigg) \cos \Bigg(\pi \Bigl( x(\frac{1} {\lambda_1} - \frac{1} {\lambda_2 }) -  (f_1 - f_2) t \Bigr) \Bigg) 
$$

近い周波数の波を同時に聴いた時、$${\displaystyle \cos \Bigg(\pi \Bigl( x(\frac{1} {\lambda_1} - \frac{1} {\lambda_2 }) -  (f_1 - f_2) t \Bigr) \Bigg) }$$の項の効果により「うなり」が起きる。

※$${\displaystyle \cos \Bigg(\pi \Bigl( x(\frac{1} {\lambda_1} - \frac{1} {\lambda_2 }) -  (f_1 - f_2) t \Bigr) \Bigg) }$$の周期は$${\displaystyle T=\frac{|f_1 - f_2|}{2}}$$である。しかし、$${\displaystyle \cos \Bigg(\pi \Bigl( x(\frac{1} {\lambda_1} - \frac{1} {\lambda_2 }) -  (f_1 - f_2) t \Bigr) \Bigg) }$$の値は$${\displaystyle T=\frac{|f_1 - f_2|}{2}}$$の間に$${2}$$回$${0}$$になるため、「うなりの周期」は$${\displaystyle |f_1 - f_2|}$$となる。

「うなりの周期」に関しては詳しくはこちらの動画の後半で解説して下さっています。


より具体的にする為、場所を固定して$${x=0}$$とすると、

$$
y(0,t)=2\sin \Big(-\pi ( f_1 + f_2) t \Big) \cos \Big( -\pi \bigl( f_1 - f_2) t \bigr) \Big) 
$$

具体計算

音速:$${v = 340\ [m\cdot s^{-1}]}$$
1つ目の波の振動数:$${f_1 = 401\ [Hz]}$$
2つ目の波の振動数:$${f_2 = 403\ [Hz]}$$
1つ目の波の波長:$${\displaystyle \lambda_1 = \frac{v}{f_1}\ [m]}$$
2つ目の波の波長:$${\displaystyle \lambda_2 = \frac{v}{f_2}\ [m]}$$
1フレームの時間:$${19}$$ミリ秒

として具体的な数値を当てはめてみると、

$$
y(0,t)=2\sin \Big(-\pi ( f_1 + f_2) t \Big) \cos \Big( -\pi \bigl( f_1 - f_2) t \bigr) \Big)  \\\ \\
=2\sin \Big(-\pi ( 401 + 403) t \Big) \cos \Big( -\pi ( 401 - 403)t \bigr) \Big)  \\\ \\ 
=-2\sin \Big(804 \pi  t \Big) \cos \Big(2 \pi t \Big) 
$$

となる。

プログラムによるアニメーション

$${y(x,t)}$$のpythonでの描画結果は以下の通り。赤い点は$${y(0,t)}$$における変位を表す。

うなりのシミュレーションy(x,t)グラフ(リアルタイムの 0.25倍速)

よく見るグラフとして、$${x}$$を固定して横軸を$${t}$$としたものがある。
今回は$${x=0}$$として$${y(0,t) = -2\sin \Big(804 \pi  t \Big) \cos \Big(2 \pi t \Big) }$$をアニメーションとして描画した。

うなりのシミュレーションy(0,t)グラフ

描画プログラム(Python)

調整は多少したが、大方はchatgptに書いて貰いました。

$${y(x,t)}$$のアニメーションはこちら

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


x = np.linspace(-5, 5, 500)
speedOfSound = 340
frequencty1 = 401
frequencty2 = 403
wavelength1 = speedOfSound / frequencty1
wavelength2 = speedOfSound / frequencty2
interval_mili_time = 19


# 波の関数
def wave(x, t):
    return np.sin(2 * np.pi * ((x / wavelength1) - (frequencty1 * t))) + np.sin(2 * np.pi * ((x / wavelength2) - (frequencty2 * t)))

# アニメーション更新関数
def update(frame):
    t = interval_mili_time * frame / 1000  # 時間がリアルタイムになるよう調整
    line.set_ydata(wave(x, t))  # yデータを更新
    point.set_data([0], [wave(0, t)])  # 点の位置を更新
    return line, point


# 描画準備
fig, ax = plt.subplots()
line, = ax.plot(x, wave(x, 0), lw=2, label="Wave")
point, = ax.plot([0], [wave(0, 0)], 'ro', label="x=0 Displacement")
# y=0の水平線を描画
ax.plot([-3, 3], [0, 0], color='black', linewidth=1.5, label="y = 0")  # y = 0
ax.set_xlim(-3, 3)  # x軸の範囲
ax.set_ylim(-8, 8)  # y軸の範囲
ax.set_xlabel("x")
ax.set_ylabel("Amplitude")
ax.set_title("Wave Animation: sin(2πx)cos(2πt)")
ax.legend()  # 凡例を追加

ani = FuncAnimation(fig, update, frames=500, interval=interval_mili_time, blit=True)

plt.show()

$${y(0,t)}$$のアニメーションはこちら

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# 時間 t の範囲を定義
t = np.linspace(0, 1.5, 699)  # 0秒から1秒まで500点
y = -2 * np.sin(804 * np.pi * t) * np.cos(2 * np.pi * t)  # y(0, t) の値を計算

# プロットの設定
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(t, y, label=r"$y(0, t) = -2\sin(804\pi t)\cos(2\pi t)$")  # 曲線をプロット
point, = ax.plot([], [], 'ro',  markersize=10, label="Moving Point")  # 動かす点
ax.set_title("Animation of $y(0, t)$", fontsize=16)
ax.set_xlabel("Time (t)", fontsize=14)
ax.set_ylabel("y(0, t)", fontsize=14)
ax.grid(True)
ax.legend(fontsize=12)
ax.set_xlim(0, 1.5)
ax.set_ylim(-8, 8)

# アニメーションの初期化関数
def init():
    point.set_data([], [])
    return point,

# アニメーションの更新関数
def update(frame):
    # フレーム数をインデックスに変換
    index = frame % len(t)  # インデックスが範囲外にならないように調整
    point.set_data([t[index]], [y[index]])  # 現在の (t, y) をプロット
    return point,

# アニメーションの作成
ani = FuncAnimation(fig, update, frames=len(t), init_func=init, blit=True, interval=17)

plt.tight_layout()
plt.show()


実際に実験をして遊んでみたい人用

スマートフォンのアプリで数$${Hz}$$異なる振動数の波を発生させるだけで無料かつ簡単に実験が可能である。


気に入ってくれたら、いいねやコメントしてね。

いいなと思ったら応援しよう!

この記事が参加している募集