波について
定常波
まず、動かない波(定常波)の基本的な形は次のように書ける:
$$
y(x) = A \sin(kx)
$$
動く波
$$
y(x,t) = A\sin(kx - \omega t) \quad \Rightarrow \quad \text{右に進む波}
$$
$$
y(x,t) = A\sin(kx + \omega t) \quad \Rightarrow \quad \text{左に進む波}
$$
各項の意味
- $k x$ :空間方向での位相変化(波が $\text{x}$ 方向に繰り返す)
- $\omega t$ :時間方向での位相変化(振動の速さ・位相の進み)
C言語での実装
test@test-fujitsu:~/kaihatsu/butsuri$ gcc moving_wave.c -o moving_wave -lSDL2 -lm
test@test-fujitsu:~/kaihatsu/butsuri$ ./moving_wave
moving_wave.c
#include <SDL2/SDL.h>
#include <math.h>
#include <stdio.h>
int main() {
const int width = 800;
const int height = 400;
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
SDL_Window *win = SDL_CreateWindow("Moving Sine Wave", 100, 100, width, height, SDL_WINDOW_SHOWN);
if (!win) {
printf("SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
if (!ren) {
SDL_DestroyWindow(win);
printf("SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
int running = 1;
SDL_Event event;
float t = 0.0f; // 時間
float dt = 0.02f; // フレーム時間の増分
float amplitude = 100.0f; // 波の高さ(振幅)
float k = 0.02f; // 波数
float omega = 2.0f; // 角速度
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) running = 0;
}
SDL_SetRenderDrawColor(ren, 0, 0, 0, 255); // 黒背景
SDL_RenderClear(ren); // 前フレームの描画内容を削除
SDL_SetRenderDrawColor(ren, 255, 255, 255, 255); // 白の波
for (int x = 0; x < width; x++) { // 画面の全横ピクセルの y(高さ)を毎回再計算
// height/2 画面の縦方向の真ん中の位置を基準にして波を上下に振動
// amplitude 振幅
// k*x 波の周期
// -omega*t … 時間 t が進むと、波全体が右に動く
float y = height/2 + amplitude * sin(k*x - omega*t);
SDL_RenderDrawPoint(ren, x, (int)y);
}
SDL_RenderPresent(ren);
SDL_Delay(16); // 約60fps
t += dt;
}
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
