弹丸运动的实现

时间:2011-07-22 02:21:25

标签: java physics

我使用用户界面在Java中创建了一个射弹运动模拟。 该程序允许用户输入初始值来计算物体的射弹。我目前没有任何东西可以将弹丸投射到屏幕上。

我有一个单独的弹簧工作线程在后台处理模拟代码。

我还添加了碰撞检测,以便当物体撞击地面时它会反弹并继续这样做,直到环路退出。

我所拥有的方程式对于我想要达到的目标是不正确的。

在以下初始条件下,输出数据的图表如下:

Initial Conditions:
Angle: 30 degrees;
Initial Speed 8.66 m/s;
Height: 50 m;
Elasticity of object: .5 coefficient of restitution in the y direction;
Acceleration: -9.8 m/s^2;
No acceleration in the x direction

enter image description here

似乎一旦模拟开始,你只会变得越来越大,所以循环永远不会自行退出。

以下是代码:

    //This class will handle all time consuming activities
class Simulation extends SwingWorker<Void, Void>
{
    //Execute time consuming task
    protected Void doInBackground() throws Exception 
    {
        FileWriter fstream = new FileWriter("output.txt");

        BufferedWriter out = new BufferedWriter(fstream);

        double angle = Double.valueOf(angleText.getText());
        double radians = angle * (Math.PI/180); 
        double vel = Double.valueOf(speedText.getText()); 
        double mass = Double.valueOf(massText.getText()); 
        double y = Double.valueOf(heightText.getText());
        double x = 0;
        double epX = Double.valueOf(epxText.getText());
        double epY = Double.valueOf(epyText.getText());
        double ax = Double.valueOf(accxText.getText());
        double ay = Double.valueOf(accyText.getText()); 

        int numBounces = 0;
        double deltaTime = .00000001; 
        double total_velocity = 0.0;
        double time = 0.0;

        String fs; 

        angle = angle * Math.PI / 180; 

        while(numBounces < 10)
        {
            //Increment Time
            time = time + deltaTime;

            //Calculate new values for velocity[x] and velocity[y]
            double vx = (vel*Math.cos(angle)) + ax*time;;
            double vy = (vel*Math.sin(angle)) + ay*time; 

            //Calculate new values for x and y
            x = x + vx*time;
            y = y + vy*time + .5*ay*(time*time); 

            System.out.format("%.3f\n", y); 

            fs = String.format("%f\t %f\t %f\t %f\t %f\t %f\t %f\t\n", ax, ay, x, y, vx, vy, time); 

            out.write(fs); 

            //If ball hits ground: y < 0
            if(y < 0)
            {
                numBounces++;

                System.out.println("Number of Bounces: " + numBounces); 

                //Why is this statement needed if the velocity in the y direction is already being reversed?
                vy = -vy - ay*time; //  vy = -vy - ay*time; 

                //Calculate angle
                angle = Math.atan(vy/vx);

                angle = angle * Math.PI / 180; 

                //Calculate total velocity
                total_velocity = Math.sqrt((vy*vy) + (vx*vx));

                //Velocity with elasticity factored in
                total_velocity = Math.sqrt((epY) * total_velocity);

                //New velocities for when ball makes next trip
                vy = total_velocity*Math.sin(angle); 
                vx = total_velocity*Math.cos(angle);

                out.write(fs); 

            }

            //Draw projectile

                //Thread.sleep(.00001); //Sleep for deltaTime - 10 nanoseconds or draw after n number of points
        }

        out.close(); 

        return null;
    }

    //SwingWorker lets you execute code on the event dispatching thread. Also allows you to update the GUI
    public void done()
    {
        try
        {               
            /*
            rangeText.setText(" " + x);
            heightTText.setText(" " + y); 
            timeText.setText(" " + time);
             */
        }

        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

可能出现什么问题? 我的猜测是它可能与角度有关。在以前版本的代码中,我没有考虑角度,它工作得很好。此外,我不确定是否必须设置GUI上的界限,以便y不会永远继续下去。

我也有一个NullPointerException。

2 个答案:

答案 0 :(得分:2)

我看到的第一个问题是:

//Calculate angle
angle = Math.atan(vy/vx);
angle = angle * Math.PI / 180; 

Math.atan返回一个弧度值:

  

返回值的反正切;返回的角度在-pi / 2到pi / 2的范围内。

所以* Math.PI / 180不会对你有所帮助。

第二个问题在这里:

//Calculate new values for velocity[x] and velocity[y]
double vx = (vel*Math.cos(angle)) + ax*time;;
double vy = (vel*Math.sin(angle)) + ay*time; 

每次通过循环,这些值都会重新初始化。由于angleaxaytime在循环期间无法更改,因此您最终会得到相同的vx和(正){ {1}}。每次循环传递时vy应该越来越小,更像是:

vy

答案 1 :(得分:-1)

例如,您需要学习使用调试器 - 在Eclipse中。然后你可以在任何你想要的地方停下来并检查变量,直到你弄清楚你在错误转弯的地方(或者在这种情况下没有采取正确的转弯)。你将能够在一分钟左右的时间内解决这个问题。

如果这不是一个选项,请开始输入关键数据的控制台printlns。

代码总是有错误,你通常无法通过查看它来解决它们 - 无论多么艰难和多长时间。