import com.rinearn.graph3d.RinearnGraph3D; import com.rinearn.graph3d.RinearnGraph3DOptionItem; import java.awt.event.WindowListener; import java.awt.event.WindowEvent; public class Sample4 implements Runnable, WindowListener { private Thread thread = null; // アニメーション用のスレッド private RinearnGraph3D graph = null; // グラフ private volatile boolean loopState = true; // ループの継続/終了を制御する // mainメソッド(最初に実行されます) public static void main(String[] args) { new Sample4(); } // 初期化・実行開始処理 public Sample4() { // グラフを起動してプロットオプションを設定(曲面プロット) this.graph = new RinearnGraph3D(); this.graph.setOptionSelected(RinearnGraph3DOptionItem.POINT, false); this.graph.setOptionSelected(RinearnGraph3DOptionItem.MEMBRANE, true); // 描画範囲の設定と自動調整機能の無効化 this.graph.setXRange(0.0, 5.0); this.graph.setYRange(0.0, 5.0); this.graph.setZRange(-1.0, 1.0); this.graph.setXAutoRangingEnabled(false); this.graph.setYAutoRangingEnabled(false); this.graph.setZAutoRangingEnabled(false); // データ更新と描画処理の関係を非同期にする(リアルタイムアニメーション用) //(※ 連番で画像出力する用途などでは行わない方がコマ落ちや欠けを防げる) this.graph.setAsynchronousPlottingEnabled(true); // グラフを閉じたら独自終了処理を行うリスナーを登録、デフォルト処理は無効化 this.graph.addWindowListener(this); this.graph.setAutoDisposingEnabled(false); // アニメーションスレッドを生成して実行開始 this.thread = new Thread(this); this.thread.start(); } // アニメーションスレッドの処理 @Override public void run() { int n = 80; // メッシュの各方向の区間数 double[][] x = new double[n+1][n+1]; //各方向の頂点数は区間数+1 double[][] y = new double[n+1][n+1]; double[][] z = new double[n+1][n+1]; // アニメーションループ(continuesLoopがtrueの間継続) for(int frame=0; this.continuesLoop; frame++) { double t = frame * 0.05; // 時刻変数 // 座標値データの更新 for(int i=0; i<=n; i++) { for(int j=0; j<=n; j++) { x[i][j] = i * (5.0/n); y[i][j] = j * (5.0/n); z[i][j] = Math.sin(x[i][j]-t) * Math.cos(y[i][j]+t) * Math.sin(Math.cos(x[i][j]+y[i][j])-2*t-0.7); } } // 座標値データをグラフに転送(非同期) this.graph.setData(x, y, z); // 50ミリ秒だけ停止(時間は適時調整) try { this.thread.sleep(50); } catch(InterruptedException e) { // 割り込み例外の処理 } } // アニメーションループが終了したらグラフを破棄 this.graph.dispose(); // スレッド処理終端: 他にスレッド・リソースが残っていなければ自然に実行終了 } // ※ 以下のようなイベント処理の実装が面倒な場合は、多少強引でよければ、 // this.graph.setAutoExittingEnabled(true); により、グラフを閉じたら // アプリケーションの実行を即終了するよう設定可能です(即席の場合向けです)。 // グラフのウィンドウが閉じられた際に行うイベント処理 @Override public void windowClosing(WindowEvent e) { // アニメーションループを脱出させ、スレッドを終了させる(結果、実行も終了) this.continuesLoop = false; } // その他のウィンドウイベント処理(ここでは何もしない) @Override public void windowDeactivated(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowIconified(WindowEvent e) { } @Override public void windowOpened(WindowEvent e) { } @Override public void windowClosed(WindowEvent e) { } }