next up previous contents
Next: 4.4 常微分方程式の力学系 Up: 4 アプレットでシミュレーション・プログラムを作る Previous: 4.2 紹介するプログラムについてコメント

4.3 1 変数関数のグラフを描く

定番の 1 変数関数のグラフを描くサンプル・プログラム DrawGraph.java (実行は http://nalab.mind.meiji.ac.jp/~mk/labo/java/sample/DrawGraph.html) は次のようにすればよい。


   1 // DrawGraph.java
   2 
   3 // <APPLET code="DrawGraph.class" width=500 height=500> </APPLET>
   4 
   5 import java.applet.*;
   6 import java.awt.*;
   7 import java.awt.event.*;
   8 
   9 public class DrawGraph extends Applet implements ActionListener {
  10 
  11   private static final String message = "graph of a function with 1 variable";
  12   private int N = 100;
  13   private double a = 0.0;
  14   private double b = 2 * Math.PI;
  15   private double wmargin = (b - a) / 10;
  16   // 座標系の変換のためのパラメーター
  17   private double ratiox, ratioy, X0, Y0;
  18   // ユーザーとのインターフェイス (パラメーターの入力)
  19   private Label labelN;
  20   private TextField inputN;
  21   private Button startB;
  22 
  23   // 準備 (変数の用意と座標系の初期化など)
  24   public void init() {
  25     //
  26     setLayout(null);
  27 
  28     labelN = new Label("N");
  29     add(labelN);
  30     labelN.setBounds(100, 60, 200, 30);
  31 
  32     inputN = new TextField("" + N);
  33     add(inputN);
  34     inputN.setBounds(300, 60, 100, 30);
  35 
  36     startB = new Button("Restart");
  37     add(startB);
  38     startB.setBounds(400, 60, 100, 30);
  39     startB.addActionListener(this);
  40   }
  41   // ボタンを押されたら、テキスト・フィールドの内容を読み取って、再描画
  42   public void actionPerformed(ActionEvent e) {
  43     if (e.getSource() == startB) {
  44       String str = inputN.getText();
  45       N = Integer.parseInt(str);
  46       repaint();
  47     }
  48   }
  49 
  50   // グラフを描きたい関数
  51   private double f(double x) {
  52     return Math.sin(3 * x) + Math.sin(5 * x);
  53   }
  54   // 座標変換の準備
  55   private void space(double x0, double y0, double x1, double y1) {
  56     X0 = x0; Y0 = y0;
  57     ratiox = 500 / (x1 - x0);
  58     ratioy = 500 / (y1 - y0);
  59   }
  60   // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
  61   private int wx(double x) {
  62     return (int)(ratiox * (x - X0));
  63   }
  64   // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
  65   private int wy(double y) {
  66     return 500 - (int)(ratioy * (y - Y0));
  67   }
  68   // x[], u[] の内容を折れ線グラフとして描く
  69   private void drawGaph(Graphics g, double x[], double u[]) {
  70     for (int i= 0; i < N; i++)
  71       g.drawLine(wx(x[i]), wy(u[i]), wx(x[i + 1]), wy(u[i + 1]));
  72   }
  73 
  74   public void paint(Graphics g) {
  75 
  76     double h = (b - a) / N;
  77     double [] u, x;
  78 
  79     // ベクトルを確保する
  80     x = new double[N+1];
  81     u = new double[N+1];
  82     for (int i = 0; i <= N; i++)
  83       x[i] = a + i * h;
  84 
  85     // タイトルを表示する
  86     g.setColor(Color.black);
  87     g.setFont(new Font("Helvetica", Font.BOLD, 24));
  88     g.drawString(message, 40, 30);
  89 
  90     // 関数値を計算する
  91     for (int i = 0; i <= N; i++)
  92       u[i] = f(x[i]);
  93 
  94     // 関数の値の範囲を調べる
  95     double min, max;
  96     min = u[0]; max = u[0];
  97     for (int i = 1; i <= N; i++) {
  98       if (u[i] > max)
  99         max = u[i];
 100       else if (u[i] < min)
 101         min = u[i];
 102     }
 103     // 関数の値の範囲を元にして座標変換を決める
 104     double hmargin = (max - min) / 10;
 105     if (hmargin == 0) hmargin = 1;
 106     space(a - wmargin, min - hmargin, b + wmargin, max + hmargin);
 107 
 108     // 関数のグラフを描く
 109     drawGaph(g, x, u);
 110   }
 111 }


next up previous contents
Next: 4.4 常微分方程式の力学系 Up: 4 アプレットでシミュレーション・プログラムを作る Previous: 4.2 紹介するプログラムについてコメント
Masashi Katsurada
平成20年2月28日