Tuesday, March 29, 2016

Cannonball Parabolic Motion

This program uses several laws of physics to simulate cannonball motion. The motion formula utilizes the Math class (sin and cos methods). The calculation is not highly accurate. It only takes into account the velocity of the cannonball (max 100 m/s), the launch angle (max 45 degrees), and gravitational force. However it should be enough to create a simple animation.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SinCos extends JFrame{
    private JTextField tf=null;
    private JTextField tf2=null;
    private JButton b=null;
    private JPanel pmain=null;
    private boolean shot=false;
    private double posx=0;
    private double posy=0;
    private CannonBall cb=null;
    
    public SinCos(){
        super("CannonBall");
        setSize(1100,400);
        
        tf=new JTextField();
        tf.setColumns(10);
        tf2=new JTextField();
        tf2.setColumns(10);
        b=new JButton("Shoot!");
        b.addActionListener(new ButtonHandler());
        JPanel ptop=new JPanel();
        ptop.setLayout(new FlowLayout());
        ptop.add(tf);
        ptop.add(tf2);
        ptop.add(b);
        
        pmain=new PanelDraw();
        pmain.setPreferredSize(new Dimension(1100,300));
        
        setLayout(new BorderLayout());
        add("North",ptop);
        add("Center",pmain);
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        show();
    }
    
    class PanelDraw extends JPanel{
        public void paintComponent(Graphics g){
            //g.clearRect(0,0,1100,350);
            super.paintComponent(g);
            Graphics2D g2=(Graphics2D)g;
            
            g2.setColor(Color.BLACK);
            
            if(shot==true){
                g2.fillOval((int)posx,pmain.getHeight()-(int)posy,10,10);
            }
        }
    }
    
    class ButtonHandler implements ActionListener{
        public void actionPerformed(ActionEvent e){
            if(e.getSource()==b){
                cb=new CannonBall();
                Thread t=new Thread(cb);
                t.start();
            }
        }
    }
    
    class CannonBall implements Runnable{
        double t=0;
        double vx=0;
        double vy=0;
                
        public CannonBall(){
            shot=true;
            double deg=Double.valueOf(tf.getText()).doubleValue();
            if(deg>45){
                return;
            }
            double rad=deg*Math.PI/180;
            
            double vel=Double.valueOf(tf2.getText()).doubleValue();
            if(vel>100){
                return;
            }
            
            //dist=2*Math.pow(vel,2)*Math.sin(rad)*Math.cos(rad)/9.8;
            
            t=2*vel*Math.sin(rad)/9.8;
            
            vx=vel*Math.cos(rad);
            vy=vel*Math.sin(rad);
        }
        
        public void run(){
            for(int i=0;i<=Math.ceil(t);i++){
                double x=vx*i;
                double y=(vy*i)-(0.5*9.8*Math.pow(i,2));
                posx=x;
                posy=y;
                try{
                    Thread.currentThread().sleep(1000);
                }catch(Exception ex){
                    
                }
                pmain.repaint();
            }
            shot=false;
        }
    }
    
    public static void main(String[] args){
        new SinCos();
    }
}

No comments:

Post a Comment