import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code="Euler_center.class" width="600" height="500" >
</applet>
*/
public class Euler_center extends Applet{   //ボタン関係
	Button btn1;
	TextField tf1,tf2;
	Label lb1,lb2;
	public void init(){
		tf1=new TextField(4);
		tf2=new TextField(4);
		lb1=new Label("Step");
		lb2=new Label("クーラン数(0<c<1)");
		btn1=new Button("描画");
		add(lb1);    add(tf1);
		add(lb2);    add(tf2);
		add(btn1);
		btn1.addActionListener(new MyListener());
	}  	                                         //↑
	class MyListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			int val1;
			double val2;
			Graphics g = getGraphics();
			g.setColor(Color.white);      //画面を白で塗りつぶす
			g.fillRect(0,100,1024,768);
			val1=Integer.parseInt(tf1.getText());
			val2=Double.parseDouble(tf2.getText());

			
			// 初期形状を描く

			double[] x;	// 初期形状の決定
                        int na = 100;	// 分割数

			x = new double[na + 1];
			for(int i = 0; i <= na; i++){
				x[i] = (double)i/2 - 10;
				if (x[i] < 0){
					x[i] = 0;}
			}

			double[] y;
			y = new double[na + 1];
			for(int i = 0; i <= na; i++){
				y[i]= (double)i - 2*14;
				if (y[i] < 0){
					y[i] = 0;
				}
			}

			double[] z;
			z = new double[na + 2];
			for(int i = 0; i <= na; i++){
				z[i] = x[i] - y[i];
				if (z[i] < 0){
			        	z[i] = 0;
				}
			}                                 //↑


			double[] phi;                
			phi = new double[na + 2];
			for(int i = 0; i <= na; i++){
				phi[i] = z[i];        //初期値
			}

                        // 初期形状の設定終了

			double c;             //クーラン数（ボタンにより指定）
			c = val2;
			double[] phi2;        //未知の値
			phi2 = new double[na + 2];
			int step_num = val1;      //時間ステップの回数（クーラン数により算出）


                       // 時間ステップの開始 

			for (int l=1 ; l <= step_num ; l++){             	//Step回数のループ

				phi[na+1] = phi[0]; //最初と最後をつなげる
				phi2[0] = phi[0] - (c/2)*(phi[1] - phi[na]); //配列に負の数が使えないためi=0を別計算


				for(int i = 1; i <= na; i++){                              //点xiの1からnaまでの計算
					phi2[i] = phi[i] - (c/2)*(phi[i+1] - phi[i-1]);    // 2次精度中心差分で計算する
				}


				for(int i = 0; i <= na; i++){		//値の入れ替え
					phi[i] = phi2[i];		//計算した値を初期値へ
				}
			}
                        // 時間ステップの終了 


			for(int i = 0; i <= na; i++){       //グラフはint表記なので小さすぎるとわからなくなるため拡大
				z[i] = z[i]*80;
				phi[i] = phi[i]*80;
			}

			double z0;               //グラフで使用する初期値
			int i0;
			double phi0;
			phi0 = phi[0];           //線を引くためのphiの初期値の指定
			z0 = z[0];
			i0 = 0;
			for (int i = 1; i <= na; i++){     //グラフの描画
				g.setColor(Color.cyan);
				g.drawLine(20 + i0,   400 - (int)z0,
				           20 + i*10, 400 - (int)z[i]);
				g.setColor(Color.blue);
				g.drawLine(20 + i0,   400 - (int)phi0,
					   20 + i*10, 400 - (int)phi[i]);
//
				z0 = z[i];                 //初期値の入れ替え
				phi0 = phi[i];
               	                i0 = i*10;
//
			}
                        double pmax = phi2[0];
                        double pmin = phi2[0];
			for (int i = 1; i <= na; i++){
				if ( pmax < phi2[i] ){
					pmax = phi2[i];
				}
				if ( phi2[i] < pmin ){
					pmin = phi2[i];
				}
			}
	                g.drawString("ポテンシャルの最大値 = " + pmax,10,18);
	                g.drawString("ポテンシャルの最小値 = " + pmin,10,35);
		}
	}
}
