gpt4 book ai didi

java - 为什么在处理大型/速度射弹时会出现不准确的情况,是由于欧拉积分吗?

转载 作者:行者123 更新时间:2023-11-30 06:51:11 25 4
gpt4 key购买 nike

所以我正在尝试进行物理模拟,其目的是模拟一枚导弹从很远的距离发射(在我的例子中,我使用了1.6公里),并且我在这个1.6公里的距离上有一个防空武器;当导弹发射时,通过数学,我已经计算出何时需要释放防空武器来击中导弹。数学太酷了,我 99% 确定这在数学上应该可行;但错误似乎发生在动画阶段,我觉得这与我处理重力的方式有关。

问题在于导弹的飞行路径不是遵循可爱的抛物线,而是采用由许多不同线性函数组成的路径(因此是欧拉积分推测(来源: http://natureofcode.com/book/chapter-5-physics-libraries/ ));我相信这与我的规模有关。我使用的比例为 1 像素 = 1 米。图像每 60 秒更新一次,所以我是说每个周期,取垂直速度 - (9.81/60),然后更新位置 (垂直速度/60)。问题是,它只想四舍五入到最近的像素,所以在前 2 秒左右,它只想让垂直位置以每个周期 4 个像素的速度变化,然后变成 5,然后 6...这导致飞行路径(当导弹以 50 度以 200m/s 的速度发射,防空炮以相同速度以 70 度发射时)如下所示:Simulation Test

如果有人知道我如何解决这个问题,将不准确的线性表示变成一个对时间仍然准确的抛物线表示(发射后的时间约为 3 秒)。如果有人有任何建议和/或解决方案,或者如果您能够解释为什么会发生这种情况并且不介意花一点时间向我解释以更好地理解问题,我们将不胜感激!如果您需要更多信息来帮助您帮助我,请发表评论,我将为您提供任何信息。相关代码片段是:

public void gravity(){
for (int i = 0; i < rockets.size(); i++){

if(timeToStart <= milliSecondTimer){
rockets.get(1).fired = true;
//Trail of other rocket
if (milliSecondTimer > 0.1 * count){
rockets.add(new Ball(rockets.get(1).x - 20 ,rockets.get(1).y - HEIGHT + 100,5,0,0,false));
}

}

if(rockets.get(i).fired){
rockets.get(i).vSpeed -= 9.81 / 60;
rockets.get(i).move(0, (int) (rockets.get(i).vSpeed / 60));
rockets.get(i).move(1, (int) (rockets.get(i).hSpeed / 60));
} else if (timeToStart==1110){
//function to work out the time displacment
derr(1);
}

//For the trail
if (milliSecondTimer > 0.1 * count){
rockets.add(new Ball(rockets.get(0).x - 20 ,rockets.get(0).y - HEIGHT + 100,5,0,0,false));
count++;
}

}
}
public static void main(String[] args) throws InterruptedException{
JFrame frame = new JFrame("App Name");
Rockets app = new Rockets();
frame.setSize((int)(WIDTH * SCALER),(int)(HEIGHT * SCALER));
frame.add(app);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.requestFocus();
long lastLoopTime = System.nanoTime();
int fps = 0, lastFpsTime = 0, count = 1;
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
//Game Loop
while(true){
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
delta = updateLength / ((double)OPTIMAL_TIME);
lastFpsTime += updateLength;
fps++;
if (lastFpsTime > 100000000 * count){
milliSecondTimer += 0.1;
count++;
}
if (lastFpsTime >= 1000000000){
System.out.println("(FPS: "+fps+")");
lastFpsTime = 0;
fps = 0;
count = 1;
}
loopsGone++;
app.repaint();
Thread.sleep( (lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000 );
}
}

谢谢,

山姆

最佳答案

也许你可以将你的 x 和 y 火箭坐标更改为 float (我假设它们现在是 int )。然后当你绘图时,就是添加 (int) 强制转换的时候。例如,

rockets.get(i).move(0, (int) (rockets.get(i).vSpeed / 60));

不应进行 int 强制转换。

而且,你会想要改变

(rockets.get(i).vSpeed / 60));

(rockets.get(i).vSpeed / 60.0)); 

您希望您的位置保持精度,但目前 int 转换并未做到这一点。这就是使用 float 所能达到的效果。

看起来规模并不是问题所在。如果您尝试在 10 x 10 像素的图像上绘制抛物线,这将是一个问题。

你能发布你的火箭类(class)吗?我想运行这个,看起来很有趣。

感谢您接受我的回答。这是我看到的另一个问题。

为了获得更好的位置精度,您需要更频繁地更新位置函数,这意味着每次重新绘制时都不止一次。这就是我的游戏循环的样子。

public void run() {
long lastTime=System.nanoTime();
final double amountOfTicks=60.0;
double ns=1000000000/amountOfTicks;
double delta=0;

int updates=0;
int frames=0;
long timer=System.currentTimeMillis();

while (running) {
long now=System.nanoTime();
delta +=(now-lastTime) / ns;
lastTime=now;
if (delta>1) {
update(); <--- this is where your gravity() method belongs
delta--;
updates++;
}
render(); <---- this will be your repaint method
frames++;
if (System.currentTimeMillis()-timer>1000) {
timer+=1000;
currUpdates=updates;
currFrames=frames;
updates=0;
frames=0;
}
}
}

它的作用是每毫秒更新一次宇宙飞船位置,但仅以 60 fps 的速度渲染。

关于java - 为什么在处理大型/速度射弹时会出现不准确的情况,是由于欧拉积分吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42742643/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com