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

我有一个单独的spring worker线程,在后台处理模拟代码。

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

我所采用的方程式与我要达到的目标不正确。

在以下初始条件下,这是输出数据图的结果:

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




看起来,一旦模拟开始,y就会越来越大,因此循环永远不会自行退出。

这是代码:

    //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。

最佳答案

我看到的第一个问题是在这里:

//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和(正)vy结尾。 vy应该随着每次循环传递而变小,更像是:

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

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

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

    //Calculate new values for velocity[x] and velocity[y]
    vx += ax * time;
    vy += ay * time;

10-04 12:40