Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

Javaアニメーションが動かない

ソースが長いので新しくスレッド立てさせていただきました。下記のソースである一定時間の間で数値シミュレーションしつつ、その間で何度か描画するという仕組みにしたのですがアニメーションが動作しなくなり困っています。尚、先程も述べた通りソースが非常に長くなっておりますがご了承ください。回答よろしくお願い致します。

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class InPen extends JPanel implements Runnable{
    
    static double t0;
    
    double r, t, rdot, tdot;
    double rh, th, rdoth, tdoth;
    
    public static void main(String[] args){
    
    JFrame wnd = new JFrame("Inverted Pendulum");
        wnd.setBounds(300, 100, 800, 700);
        wnd.add(new InPen());
        wnd.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});
        wnd.setVisible(true);
    }
    
    public InPen(){
    
        UIManager.put("OptionPane.okButtonText", "OK");
        UIManager.put("OptionPane.cancelButtonText", "Cancel");
        
        String inputValue;
        inputValue = JOptionPane.showInputDialog(null, "Please input a value of t0 (degree)", "Input t0", JOptionPane.PLAIN_MESSAGE);
    
        t0 = Double.parseDouble(inputValue);
        t0 = degreetoradian(t0);
        
        Thread thr = null;
        if(thr == null){
            thr = new Thread(this);
            thr.start();
        }
    }
    
    public void run(){
    double r0 = 0.0, rr0 = 0.00, tt0 = 0.00;
        r = r0; t = t0; rdot = rr0; tdot = tt0;
        
        try{
            Thread.sleep(1000);
        }catch(Exception e){
        e.printStackTrace();
    }
    
    SwingUtilities.invokeLater(new Runnable(){
        public void run() {
            move();
        }
        });
    }
    
    public void move(){
    
        double step = 0.0001;
    double time = 0.01;
        for(double i = 0; i <= 1000; i = i + step){
        
        rh   = r    + step * dadt(r, t, rdot, tdot);
        th   = t    + step * dbdt(r, t, rdot, tdot);
        rdoth = rdot + step * dcdt(r, t, rdot, tdot);
        tdoth = tdot + step * dddt(r, t, rdot, tdot);
        
        r = rh; t = th; rdot = rdoth; tdot = tdoth;
        if(i == time){
            try{
            repaint();
            Thread.sleep(30);
        }catch(Exception e){
            e.printStackTrace();
        }
        time = time + 0.01;
        }
        }
    System.exit(0);
    }
    
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        int s = getSize().width/2,a = 1000;
        
        g.drawLine((int)(s+r*a-20)-100,375,(int)(s+r*a+20)+100,375);
        g.drawLine((int)(s+r*a+20)+100,375,(int)(s+r*a+20)+100,425);
        g.drawLine((int)(s+r*a-20)-100,425,(int)(s+r*a+20)+100,425);
        g.drawLine((int)(s+r*a-20)-100,375,(int)(s+r*a-20)-100,425);
        g.drawLine(0,450,s*2,450);
        g.drawLine(s,450,s,455);
        g.fillOval((int)(s+r*a-15)-65,400,50,50);
        g.fillOval((int)(s+r*a+5)+25,400,50,50);
        g.drawLine((int)(s+r*a),375,(int)(s+r*a+105.0f*Math.sin(t)),(int)(375-110.0f*Math.cos(t)));
        g.fillOval((int)(s+r*a+110.0f*Math.sin(t))-5,(int)(370-115.0f*Math.cos(t)),10,10);
    }
    
    
    double dadt(double r, double t, double rdot, double tdot){
    double m = 0.1, M = 5.01, l = 0.115, R = 24.5;
        double drdot, dtdot;
        drdot = dcdt(r, t, rdot, tdot);
        dtdot = dddt(r, t, rdot, tdot);
    
        return (1 / R) * (m * l * Math.sin(t) * tdot * tdot - (M + m) * drdot - m * l * Math.cos(t) * dtdot);
    }
    
    double dbdt(double r, double t, double rdot, double tdot){
    double m = 0.1, J = 0.00214, l = 0.115, g = 9.8, c = 0.000598;
        double drdot, dtdot;
        drdot = dcdt(r, t, rdot, tdot);
        dtdot = dddt(r, t, rdot, tdot);
    
        return (1 / c) * (-m * l * Math.cos(t) * drdot - (J + m * l * l) * dtdot + m * l * g * Math.sin(t));
    }
    
    double dcdt(double r, double t, double rdot, double tdot){
        double u = 0.0, m = 0.1, M = 5.01, J = 0.00214, l = 0.115;
        double g = 9.8, R = 24.5, c = 0.000598, a = 30.9;
        return ((J + m * l * l) *(-R * rdot + m * l * Math.sin(t) * tdot * tdot + a * u) + (-m * l * Math.cos(t)) * (-c * tdot + m * g * l * Math.sin(t))) / ((M + m) * (J + m * l * l) - m * m * l * l * Math.cos(t) * Math.cos(t));
    }
    
    double dddt(double r, double t, double rdot, double tdot){
        double u = 0.0, m = 0.1, M = 5.01, J = 0.00214, l = 0.115;
        double g = 9.8, R = 24.5, c = 0.000598, a = 30.9;
        return ((-m * l * Math.cos(t)) * (-R * rdot + m * l * Math.sin(t) * tdot * tdot + a * u) + (M + m) * (-c * tdot + m* g * l * Math.sin(t))) / ((M + m) * (J + m * l * l) - m * m * l * l * Math.cos(t) * Math.cos(t));
    }
    
    double degreetoradian(double degree){
    return degree / 180.0 * Math.PI;
    }
}

11

回答

81705

閲覧

11件の回答

評価

0

続きでいいんだよ、そういうのは。
それと、ソースをそのまま載せて「分かりません」という質問のほう
が問題。
こういうとこでは、自分がやってみたことを明示した上で、現象を再
現できるミニマムコードで依頼するんだよ。
ミニマムコードって何?なんて質問はしないようにね。
それこそ「ぐぐれ」だから。

評価

0

>$さん
すみませんでした。このコードのどこを削ればいいかが分からずそのまま書いてしまいました。恐らく数値計算部分を削ると動かなくなると思ったので。以後質問の仕方に気をつけます。
改めて、move()の中で数値シミュレーションをしつつ描画するようにしたつもりなのですが上手く動きません。move()の中でif(i == time)で再描画をやってみたのですが動かず困っています。もし回答していただけるならよろしくお願い致します。

評価

0

試しにmove()のforループのiの値を出してみたら0.0001ずつ足されるはずなのにたまに誤差が生じていることが分かりました。この誤差を改善する方法が分かる方いましたら教えていただけませんか?

評価

0

>誤差

丸め誤差じゃないの?
stepを1にして、もちろん他の値も10000倍にして、
値を使用する直前に10000で割るようにすれば。

評価

0

>不良社員さん
ありがとうございます。やってみますね。

評価

0

「丸め」について調べてみたのかね。
答えが得られたからやってみた。
できればok、できなかったらまた質問じゃ、進歩ないよ。

評価

0

>$さん
調べることを前提に回答致しました。

評価

0

それなら「やってみます」じゃなくて「調べてみます」だろうなあ。

評価

0

>$さん
今後は言葉遣いについても気をつけていきたいと思います。ご指摘ありがとうございました。

評価

0

その後どうなんでしょうか。
何か話題がアニメを動くようにするのとは違った方向のようですが?
まず、動くようにするには、move() から素早く戻って
SwingUtilities.invokeLater(new Runnable() 内の run() を終わらせることで
す。run() が終わるまで描画を含めた Swing のほかの動作がブロックされて
しまい画面は動きません。

Swing の動作と使い方についての理解を深めてください。

評価

0

>仙人さん
未だに動いてません。もう少し自分で調べてそれでも解決しない場合はまた質問させていただきたいなと考えております。Swing の動作と使い方について詳しく調べてみたいと思います。ありがとうございます。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。