【问题标题】:How can I relate the Java Timer to milliseconds in real time, and update a time variable accordingly?如何将 Java Timer 与毫秒实时关联,并相应地更新时间变量?
【发布时间】:2017-04-24 14:01:43
【问题描述】:

我一直在编写一些关于弹丸运动的代码。我启动了一个计时器 t 并为其使用了构造函数 10,每个动作事件我将 0.01 添加到初始化为 0.00 的时间变量中,以模拟时间过去。使用这段时间我计算高度/距离等。我无法弄清楚 2 个问题:

1) 将当前时间打印到控制台时,它会保留许多小数位,运行代码。 2) 高度会一直增加,虽然不应该增加,感觉好像是加速的正负作用。

(我的面板是 1920x1080,面板动画占用 80 像素 - 这就是为什么它是 1000-50)(1000 半径)

使用图片:http://imgur.com/a/UF9eL

来自回复: 1) 忘记将 vy 乘以 t。 2)使用DecimalFormat截断值

感谢@G_H; @砖; @汤姆; @Diginoise 代码:

package projectV1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class Animate extends JPanel implements ActionListener {

double x = 0;
double time = 0.00;
String timeText2 = "0";
double y = 1000;
double velY = 0.0;
double velX = 0.0;
public static Timer t;

public Animate() { // Constructor
    super(); 
}

public void start(String acceleration, String initialVelocity, String angle){



    new Ball(acceleration, angle, initialVelocity);

    t = new Timer(10, this);
    t.start();

    }


@Override
 public void actionPerformed(ActionEvent e) {
    updateTime(); 
    move();


      }

 public void move(){ // HOlds the repaint method
        x = x + Ball.getVelX();
        Simulation.distanceText.setText(Double.toString(Ball.getDistance(time))); // Some of these are just checks for me in the gui
        Simulation.velocityText.setText(Double.toString(time));
        y = y- Ball.getVelY(time);
        Simulation.heightText.setText(Double.toString(Ball.getHeight(time)));



        repaint();
    }

 public void updateTime(){
     time= time + 0.01;

     System.out.println(Double.toString(time));  // Using this as a test to check the time output.
     timeText2 = Double.toString(time);
     Simulation.timeText.setText(timeText2);
     }


public void paintComponent(Graphics gg){
    super.paintComponent(gg);
    gg.drawRect(0, 0, 1920, 1000);
    Graphics2D g = (Graphics2D) gg;

     Ellipse2D.Double shape = new Ellipse2D.Double(x, y-50.0, 50, 50);
        g.fill(shape);

    // g.fillOval(x, y-50, 50, 50);

     }
}

来自“球类”的代码

public Ball(String acceleration, String angle, String initialVelocity ) {

    Ball.acceleration = acceleration;
    Ball.initialVelocity = initialVelocity;
    Ball.angle = angle;
}


public static double getVelX(){ //  This stays constant throughout the program
    double velX = 0.0;
    int u = Integer.parseInt(initialVelocity);
    double ang = Double.parseDouble(angle);
    velX = u*(Math.cos(ang));
    return velX;

}

public static double getVelY(double time ){

    double velY = 0.0 ;
    double ang, acc = 0;
    int u = 0;
    ang = Double.parseDouble(angle);
    acc = Double.parseDouble(acceleration);
    u = Integer.parseInt(initialVelocity);

    velY = u*(Math.sin(ang))- (acc*time);
    return velY;
}

public static double getDistance(double time){
    double distance = 0;
    double ang = 0;
    int u = 0;
    ang = Double.parseDouble(angle);

    u = Integer.parseInt(initialVelocity);
    distance = (u*time)*(Math.cos(ang));

    return distance;


}
public static double predictedTime(){
    double ptime = 0;
    double ang = 0;
    ang = Double.parseDouble(angle);
    int u = Integer.parseInt(initialVelocity);
    ptime = ((u*u)*(Math.sin(ang)*Math.sin(ang))/(2*9.81));

    return ptime;
}

public static double getHeight(double time ){
    double height;
    double ang, acc;
    int u = 0;
    ang = Double.parseDouble(angle);
    acc = Double.parseDouble(acceleration);
    u = Integer.parseInt(initialVelocity);
    height = u*(Math.sin(ang))-(0.5*acc*(time*time));

    return height;


}

【问题讨论】:

  • 我不认为这是一个四舍五入的问题,老实说我以前见过,我认为它没有帮助。如果是,那么我错了,但正如你所见,这不是这里唯一的问题。我试过: Math.round(time*100)/100 但它不起作用
  • 如果你需要物理部分的帮助,我建议你写出你认为你正在使用的方程。与您说要解决的问题相比,我无法快速理解您的代码。
  • 你说的小数位数问题几乎肯定是四舍五入的错误,可以按照@Tom提供的链接中的说明进行控制。
  • 是的,我将在接下来的 5 分钟内添加我正在使用的 5 个屏幕截图。我试图舍入它,但它只是停留在 0.0。如果您可以帮助我如何实例化计时器并将其与“实时”毫秒相关联,那将是惊人的。屏幕将在接下来的 5 分钟内启动

标签: java timer simulation physics projectile


【解决方案1】:

1) 将当前时间打印到控制台时,它会保留许多小数位,运行代码。

这是由于小数的二进制表示。假设我们尝试用十进制表示 1/3,你得到 0.333333... 展开是无限的,没有有限的表示。 0.01 (1/100) 有十进制的有限表示,但不是二进制的。所以如果你写double d = 0.01;,知道内部二进制表示是一个近似值,而不是精确值。您需要将输出截断为具有一定小数位数的某个值。查看class DecimalFormat,了解以特定格式输出值。

2) 高度会一直增加,虽然不应该增加,感觉好像是加速的正负作用。

查看此部分:velY = u*(Math.sin(ang))- (acc*time);

u 是一个常量。 sin(ang) 也是如此。 acc*time 只会增加。所以 velY 将线性变化是有道理的。你已经发布了这个:

它声明Sy = Vy*t - 0.5*g*t²,然后是Vy = u*sin(ang)。方程的展开中缺少一个时间分量。应该是这样的:velY = (u*(Math.sin(ang))- (acc*time)) * time; 或(理论上相同)velY = u*(Math.sin(ang))*time - (acc*time*time); 注意acc 必须是 1/2 g。如果您提供 g 作为加速度,您需要根据 formula for vertical displacementacc*time*time 乘以 0.5。

最后注意,你将各种字段变成类 Ball 的静态字段,然后在构造函数中分配它们。最好不要那样做。使字段accelerationinitialVelocityangle Ball 的 instance 字段(它们可以是最终的,因为它们不会改变)并使方法非静态。例如,这将允许您模拟多个球,因为它们的值对它们来说是本地的,而不是共享的类状态。

【讨论】:

  • 非常感谢您对我的问题的反馈,我似乎忘记了第一个问题中的时间元素,这是我的错误。在此之前我不知道十进制格式,所以谢谢你让我知道它。然而,关于你提出的最后一点,如果我没有将它们设为静态,我无法从我的 move() 方法访问 Ball 类中的方法来获取 velX 和 velY,但我可以试试这个。再次非常感谢您抽出宝贵时间,我会尽快添加这些更改并返回此评论部分。这是我的第一个主要学校项目,很抱歉这种奇怪的风格
  • 为了访问这些方法,您必须创建一个 Ball 实例并在该实例上调用方法。例如:Ball b1 = new Ball("9.81", "10", "0.78"); b1.getDistance(time); 类是该类的实例(对象)的模板。这些实例有它们自己的局部变量,并且调用它们的方法在该特定实例上运行。这是面向对象编程的核心方面。过了一会儿,这些概念会“点击”,你就会明白它们的好处是什么。例如,您可以轻松地制作具有自己的角度和速度的多个 Ball 实例。
  • 我确实尝试过这个,但是因为我的移动没有​​访问我将初始化 b1 的区域,所以我没有选择执行 b1.getDistance。如果我打算添加多个球,我可以试一试,看看效果如何。再次感谢你们的帮助,如果不是你们,我就不会发现 Vy*t。我现在有正确工作的高度并且球不会落在屏幕下方。我想问一下,您是否知道如何缩放程序,以便我可以在 JPanel 中显示整个模拟?
  • @HarisRabbani 这可能最好在单独的问题中提出。但是,它不应该太难。在某个虚拟坐标系中进行计算(让 y 轴从 0 开始并将“向上”作为正数而不是倒置的 JPanel 坐标可能更容易),然后在渲染之前通过缩放将它们转换为可见坐标(乘法/除法)、平移(加法/减法)和反转 y 轴。您需要保持 x 和 y 坐标的缩放比例相同,才能看到真实的轨迹。
  • 另外,为了在面板上放置所有内容而不必“平移”相机,您需要首先计算球的着陆位置并使用相对于面板的“真实”距离width 知道如何缩放事物。您需要对最高点和面板高度执行相同操作,以确保球不会垂直夹在屏幕之外。使用两个方向的最大水平/垂直比例因子来保持真实的路径。如果垂直和水平缩放不同,它会改变可见轨迹。
猜你喜欢
  • 2021-01-21
  • 2020-04-15
  • 1970-01-01
  • 2015-04-10
  • 2017-04-25
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 2017-05-15
相关资源
最近更新 更多