/* * Heat1d_e_3.java * 1998年9月20日 (子供が産まれるちょっと前だったわけか) * * コンパイル: javac Heat1d_e_3.java * 実行: appletviewer Heat1d_e_3.java * * * * 注意 * 何と言っても古いので JDK1.1 以降では警告される。 * (1) reshape() よりも setBounds() を使えと言われる (置き換えれば OK)。 * (2) action() もよせ、と言われる。 */ import java.applet.*; import java.awt.*; public class Heat1d_e_3 extends Applet { static final boolean DEBUG = false; // true; private static final String message = "1D Heat Equation"; private int N = 40; private double Tmax = 0.5, lambda = 0.5; // 座標系の変換のためのパラメーター private double ratiox, ratioy, X0, Y0; // ユーザーとのインターフェイス (パラメーターの入力) private Label labelLambda, labelN; private TextField inputLambda, inputN; private Button startB; // 準備 (変数の用意と座標系の初期化など) public void init() { // setLayout(null); labelLambda = new Label("lambda (should be <= 1/2)"); add(labelLambda); labelLambda.setBounds(100, 100, 200, 30); inputLambda = new TextField("" + lambda); add(inputLambda); inputLambda.setBounds(300, 100, 100, 30); labelN = new Label("N"); add(labelN); labelN.setBounds(100, 130, 200, 30); inputN = new TextField("" + N); add(inputN); inputN.setBounds(300, 130, 100, 30); startB = new Button("Restart"); add(startB); startB.setBounds(250, 180, 50, 30); space(-0.1, -0.1, 1.1, 1.1); } // ボタンを押されたら、テキスト・フィールドの内容を読み取って、再描画 public boolean action(Event evt, Object what) { if (evt.target == startB) { String str1 = inputLambda.getText(); String str2 = inputN.getText(); lambda = Double.valueOf(str1).doubleValue(); N = Integer.parseInt(str2); repaint(); } return true; } // 初期条件 private double f(double x) { if (x <= 0.5) return x; else return 1-x; } // 座標変換の準備 private void space(double x0, double y0, double x1, double y1) { X0 = x0; Y0 = y0; ratiox = 500 / (x1 - x0); ratioy = 500 / (y1 - y0); } // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系) private int wx(double x) { return (int)(ratiox * (x - X0)); } // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系) private int wy(double y) { return 500 - (int)(ratioy * (y - Y0)); } // x[], y[] の内容をグラフにする private void drawGaph(Graphics g, double x[], double u[]) { for (int i= 0; i < N; i++) g.drawLine(wx(x[i]), wy(u[i]), wx(x[i + 1]), wy(u[i + 1])); } public void paint(Graphics g) { double h = 1.0 / N; double tau = lambda * h * h; double dt = 0.01; int Jmax = (int) (Tmax / tau); int skip = (int) (dt / tau + 0.5); double [] u, unext, x; // ベクトルを確保する x = new double[N+1]; u = new double[N+1]; unext = new double[N+1]; for (int i = 0; i <= N; i++) x[i] = i * h; // これはあんまり意味がない。 g.setColor(Color.pink); g.fillOval(10, 10, 330, 80); g.setColor(Color.red); for (int i=0; i<4;i++) g.drawOval(10-i, 10-i, 330+2*i, 80+2*i); // タイトルを表示する g.setColor(Color.black); g.setFont(new Font("Helvetica", Font.BOLD, 24)); g.drawString(message, 40, 75); // 初期値を計算する for (int i = 0; i <= N; i++) u[i] = f(i * h); // 初期値のグラフを描く drawGaph(g, x, u); // 時間に関するループ for (int j = 1; j <= Jmax; j++) { int i; for (i = 1; i < N; i++) unext[i] = (1 - 2 * lambda) * u[i] + lambda * (u[i-1] + u[i+1]); for (i = 1; i < N; i++) u[i] = unext[i]; u[0] = 0; u[N] = 0; if (DEBUG) for (i = 0; i <= N; i++) System.out.println("u[" + i + "]=" + u[i]); // 適当な間隔 (dt=0.01) でグラフを描く if (j % skip == 0) drawGaph(g, x, u); } } }