GUIアプリケーションの挑戦

プログラミング初心者ですが頑張ります。いろんな言語に興味があります。GUIやデータベース関連のアプリケーションを開発しています。

Jebis 第二回 ユーザーからの値を受け取ってグラフを完成させる

前回は方眼を描画しました。
Jebis 第一回 グラフの描画 - GUIアプリケーションの挑戦
さて今回はユーザーからの値を受け取って実際に放物線を描画したいと思います。
GUIアプリケーションなのでJButtonにActionEventを発生させてみます。

まず、値を入力できるSettingsクラスを作りましょう。描画にGraphクラスが必要なのでコンストラクタで渡します。
ユーザーの値はJTextFieldで取得します。

ご存知の通り、
斜方投射の式は初速をV0, 投射角度をθ, 初期高度をy0,時間をtとすると

f:id:mnagn:20160823231213p:plain
f:id:mnagn:20160823231142p:plain
となります。

今回はただグラフを描画するだけですので、
ユーザーから欲しい値は初速、初期高度、投射角度です。

//_fはそれぞれのJTextFieldオブジェクト
//gはグラフオブジェクト
//重力加速度は定数 GRAVITYで定義します。
public void ActionPerformed(ActionEvent e)
{
     //ユーザーからの値をdouble型に変換していきます。
     double speed = Double.parseDouble(speed_f.getText());
     double ini_height = Double.parseDouble(ini_h_f.getText());
     double pitch = Double.parseDouble(pitch_f.getText());
     double[2] xy = new double[2];
     xy[0] = 0.0;
     xy[1] = ini_height;//毎回足すのはコードが長くなるので最初に足しときます。
     g.setIniPoint(xy);//後記
   y = ini_height;
     double t = 0.002;//0.002s
     while(true){
         vecX = speed*t*Math.cos(deg2rad(pitch));
         vecY = -(GRAVITY * Math.pow(t,2))/2 + speed*t*Math.sin(deg2rad(pitch));
         if(y + vecY < -10){//落差が大きいと最後まで表示できない可能性があるため
             break;
         }
         xy[0] = vecX;
         xy[1] = vecY+y;
         g.addPoint(xy);
         t+=0.002;
      }
}

public double deg2rad(double a)
{
     return a * (Math.PI / 180);
}

長くなりました。。。ちょっと休憩....
よし、やりましょう。長いですが計算をしただけなのでそこまで難しくはないと思います。
コメントで後記としたのはGraphクラスに追加する関数です。
Graph.java

public ArrayList<double> ps = new ArrayList<double>();
public void setIniPoint(double[] xy)
{
    ps.add(xy[0]);
    ps.add(xy[1]);
}

public void addPoint(double[] xy)
{
    ps.add(xy[0]);
    ps.add(xy[1]);
    repaint();//再描画
}

前回の線と後ろの描画の処理の後にグラフの点を打って結ぶ処理を書きます。

public void paintComponent(Graphics g)
{
    drawBoard(g);
    drawGraph(g);
    drawPoint(g);
}

public void drawPoint(Graphics g)
{
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.RED);
    BasicStroke wideStroke = new BasicStroke(4.0f);//太さ
    g2.setStroke(wideStroke);
    for (int i = 0; i < ps.size()-2; i+=2) {
        double x = (double) ps.get(i)*(masu*2);//始点x
	double y = (double) ps.get(i+1)*(masu*2);//始点y
	double nx = (double) ps.get(i+2)*(masu*2);//終点x
	double ny = (double) ps.get(i+3)*(masu*2);//終点y

	g2.draw(new Line2D.Double(x, HEIGHT-y, nx, HEIGHT-ny));
    }
}

Graphics2DクラスとLine2Dクラスを使ったのは曲線を引くためです。
GraphicsクラスのdrawLine関数だと、引き値がすべてint型でないといけないので
グラフには向いていないんですね。
毎回2を足すのはxのキーは偶数にあるからです。

試しにスピードを15m/s、角度を42°、初期高度を2(m)とすると
f:id:mnagn:20160824123142p:plain
写真のようになるかなと思います。

今回はここまでで。コードが多くなってしまいました。
次回は短くしますぅ。。。