« タブとスペース | トップページ | 大学一年生って »

2008/07/14

グラフの表示を遅延

Gnuplotのグラフアニメーションをじっくり見るために、時間制限付きキー入力待ちをselect()関数を使って実装しようとしていたけど、Gnuplotのpauseコマンドを使えば表示を遅延させられることを発見した。(なんで始めにGnuplotの機能を調べないんだ・・・)

使い方は簡単。

> pause time

ex)  > pause 0.1

コレだけ。timeのところに遅延させたい時間を記述する。(恐らく単位は秒)

プログラムに組み込むときも、一行で済むから簡単。

実際どんな動きになるかは、下のサンプルプログラムを実行してみるとわかる。

/*
  $ gcc -Wall -O fou1.c -lm
  でコンパイル
*/
#include <stdio.h>
#include <math.h>

/* Parameter */
#define PERIOD    2*M_PI    // 区間
#define EDGE_L   -PERIOD/2  // 区間の左の端点
#define NP        1000      // プロットする点の数
#define DP        PERIOD/NP // 点と点の距離      
#define N_MAX     101       // 重ね合わせる回数

/*
  周期関数
   f(t) = -1 (-pi < t <= 0 )
        =  1 (  0 < t <= pi)
  フーリエ級数展開
   f(t) ~ a_0 + coef * sigma(n=1 -> inf){a_n*cos(var_a) + b_n*sin(var_b)}
   f(t) ~ 1/2 + 2/pi * sigma(n=1 -> inf){sin(2n-1)t/(2n-1)}
  座標データ
   f(t) = pt[NP]
     t  = EDGE_L + DP * ip (0 <= ip < NP)
*/

void func_t(double pt[], int n_max)
{
  int ip, in;
  
  for(ip = 0; ip < NP; ip++){
    double sigma = 0;
    double t     = EDGE_L + DP * ip;
    double a_0   = 1.0/2.0;
    double coef  = 2.0/M_PI;
    for(in = 1; in <= n_max; in++){
      double a_n   = 0;
      double var_a = 0;
      double b_n   = 1.0/(2.0*in-1.0);
      double var_b = (2.0*in-1.0)*t;
      
      sigma += a_n * cos(var_a) + b_n * sin(var_b);
    }
    pt[ip] = a_0 + coef * sigma;
  }
}

void gnuplot_run(FILE *gp, const double pt[], int n_max)
{
  int ip;
  fprintf(gp, "set terminal x11\n"); // gnuplot4.2.2ではwxtが不安定
  fprintf(gp, "unset key\n");
  fprintf(gp, "set title \"n=%d\"\n", n_max);
  fprintf(gp, "plot '-' w l\n");
  for(ip = 0; ip < NP; ip++){
    double t = EDGE_L + DP * ip;
    fprintf(gp, "%g %g\n", t, pt[ip]);
  }
  fprintf(gp, "end\n");
  fprintf(gp, "pause %g\n", 0.05); // pauseコマンドで指定秒数だけ遅延
  fflush(gp);
}
	      
int main(void)
{
  static double pt[NP];
  FILE *gp = popen("gnuplot -persist\n", "w");
  
  int in;
  for(in = 1; in <= N_MAX; in++){
    func_t(pt, in);
    gnuplot_run(gp, pt, in);
  }
  pclose(gp);

  return 0;
}

このプログラムはフーリエ級数が元の周期関数に近づく様子を見るために作ったもの。

pauseコマンドの部分をコメントアウトするとスピードが速すぎてじっくり見れない(マクロN_MAXを11とかにするとそりゃぁもう)けど、pauseをいれておけば様子がじっくり見れる。

他の周期関数が見たい人は自分でフーリエ級数展開しませう。

|

« タブとスペース | トップページ | 大学一年生って »

C」カテゴリの記事

Numerical Computing」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/222903/41841637

この記事へのトラックバック一覧です: グラフの表示を遅延:

« タブとスペース | トップページ | 大学一年生って »