next up previous contents
Next: 3.4.2.0.2 問題2: Up: 3.4.2 簡単な動画 Previous: 3.4.2 簡単な動画

3.4.2.0.1 例題2:

時刻 $ t$, 位置 $ x\in[0,2\pi]$ における変移が $ f(x,t)=\sin x\cos t
+\sin 3x\cos 3t + \sin 5x\cos 5t$ で与えられる弦の振動を描け3.6

現代では常識になっていることだが、実際に連続的に図を変化させなくても、 十分素早く図を切り変えれば「連続的に動いている」ように見える。適当な時 間間隔 $ \Delta t$ を定めて、時刻 $ t_j=j\Delta t$ ( $ j=0,1,2,\cdots$) に おける $ x$ の関数 $ f(x,t_j)$ のグラフを次々に描けばよいであろう。以下 では、古いグラフを消すために erase() を用いている。

* reidai2.f -- 簡単な動画 (紙芝居?)
      program rei2
*      変数の宣言
      integer i,N,j,Jmax
      real Pi,a,b,margin
      real Time,h,dt,t,x,f
      external f
*      Pi=円周率, a=区間の左端, b=区間の右端, margin=余白
      Pi = 4.0 * atan(1.0)
      a = 0.0
      b = 2.0 * Pi
      margin = (b - a) / 20
*      x軸の区間の分割数、追跡時間の入力
      write(*,*) ' x軸上の区間の分割数='
      read(*,*) N
      write(*,*) ' 追跡時間='
      read(*,*) Time
*      区間の刻み幅
      h = (b - a) / N
*      グラフィックスの初期化
      call openpl
      call fspace2(a - margin, -2.0, b + margin, 2.0)
*      時間間隔を決め、ループの回数を計算する
      dt = 1.0 / 16.0
      Jmax = Time / dt + 0.5
******** メイン・ループ ********
      do j=0,Jmax
        t = j * dt
        call erase
        call fmove(a, f(a,t))
        do i = 1, N
          x = a + i * h
          call fcont(x, f(x,t))
        end do
        call xflush
      end do
****** メイン・ループ終り ******
*      グラフィックスの後始末
      call closepl
      end
******************************************
*      両端を固定された弦のある3つの固有振動の和
*      時刻 t=0 では、例題1 に現われる関数に一致する
      real function f(x,t)
      real x,t
      f = sin(x)*cos(t)+sin(3*x)*cos(3*t)+sin(5*x)*cos(5*t)
      end


/*
 * reidai2.c -- 簡単な動画 (紙芝居?)
 *  How to compile: ccx reidai2.c
 */

#include <stdio.h>
#include <math.h>
#include <fplot.h>

int main()
{
    /* 変数の宣言 */
    int i, N, j, Jmax;
    double Pi, a, b, margin;
    double Time, h, dt, t, x, f(double, double);
    /* Pi=円周率, a=区間の左端, b=区間の右端, margin=余白 */
    Pi = M_PI;
    a = 0.0;
    b = 2.0 * Pi;
    margin = (b - a) / 20;
    /* x軸の区間の分割数、追跡時間の入力 */
    printf("x軸上の区間の分割数=");
    scanf("%d", &N);
    printf("追跡時間=");
    scanf("%lf", &Time);
    /* 区間の刻み幅 */
    h = (b - a) / N;
    /*  グラフィックスの初期化 */
    openpl();
    fspace2(a - margin, -2.0, b + margin, 2.0);
    /* 時間間隔を決め、ループの回数を計算する */
    dt = 1.0 / 16.0;
    Jmax = Time / dt + 0.5;
    /* ******* メイン・ループ ******* */
    for (j = 0; j <= Jmax; j++) {
        t = j * dt;
        erase();
        fmove(a, f(a, t));
        for (i = 1; i <= N; i++) {
            x = a + i * h;
            fcont(x, f(x, t));
        }
        xflush();
    }
    /* ***** メイン・ループ終り ***** */
    /* グラフィックスの後始末 */
    closepl();
    return 0;
}

/*
 * 両端を固定された弦のある3つの固有振動の和
 * 時刻 t=0 では、例題1 に現われる関数に一致する
 */

double f(double x, double t)
{
    return sin(x) * cos(t) + sin(3 * x) * cos(3 * t) + sin(5 * x) * cos(5 * t);
}

これもコンパイルして実行してみよう。
Fortran の場合

oyabun% f77x reidai2.f

reidai2.f:
MAIN rei2:
f:
oyabun% reidai2
x軸上の区間の分割数=
100
追跡時間=
6.28 ← (一周期分)
oyabun%

C の場合

oyabun% ccx reidai2.c

oyabun% reidai2
x軸上の区間の分割数=100
追跡時間=6.28
oyabun%

長い追跡時間を指定した場合は、停止させたくなったときに C-C (コントロー ル C) を打てば止めることができる。


next up previous contents
Next: 3.4.2.0.2 問題2: Up: 3.4.2 簡単な動画 Previous: 3.4.2 簡単な動画
Masashi Katsurada
平成18年4月28日