在c中从地面射出的弹道炮弹

时间:2018-06-01 11:51:10

标签: c loops while-loop physics

我去年开始学习编码。虽然不是很好。 我试图用c语言绘制从地面射出的炮弹的轨迹。 (无论如何,我没有单独编码)。

(#对不起,我必须删除原始代码一段时间。如果您想查看原始代码,请告诉我。但我确定如果您只是完全足够请参阅下面的选定答案。)

如果我执行它,结果是这样的。

the speed is?
6
the angle is
32
the spring is
0.4
X=0.000000, Y=0.000000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000
X=0.000000, Y=-0.049000

我试图弄清楚我做错了什么,但我根本不知道。 请帮帮我!

1 个答案:

答案 0 :(得分:4)

这种方法的问题是Y坐标可能变为负值。一旦它完成,如果初始速度不够高,球可能会卡在表面下方,如@RetiredNinja的结果所示(坐标在-0.049处被卡住了这是不正确的行为。)

原始代码的错误结果(不按比例缩放),修改后的参数:

enter image description here

球似乎"隧道"通过地面(一些值低于零)。

如何解决这个问题?我们需要正确地解决碰撞,确保球反弹而不是越过表面边界。为此,让我们在发生反弹的时间步长内检查球的行为。

enter image description here

垂直速度和垂直位置均为负时发生碰撞。要找到碰撞时间和速度,请使用运动方程:

enter image description here

一旦我们获得了碰撞速度,我们就可以简单地将新的垂直速度更新为-spring * vcspring应该有更好的名称,例如coef_rest);另一个好处是我们不再需要拨打pow

在时间步长期间可能会发生这种情况,因此我们需要在循环中执行此操作。另外需要注意的是,随着垂直速度衰减,弹跳变得无限频繁 - 所以我们需要一个"截止"阻止球弹跳的速度。

代码:

#include <stdio.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.141592654
#endif

int main()
{
   const double g = 9.81;        // gravity
   const double dt = 0.025;      // time step
   const double maxtime = 5.0;   // max time
   const double spring = 0.95;   // coefficient of restitution
   const double cutoff = 1e-4;   // cut-off velocity

   double speed = 6;
   double angle = 32;
   angle = angle * M_PI / 180.0;

   double init_vx = speed * cos(angle);
   double init_vy = speed * sin(angle);

   int springnumber = 0;

   printf("0.0,0.0\n");
   for (double ts = 0.0, vs = init_vy, time = dt; time <= maxtime;)
   {
      // positions *after* this time step
      double px = time * init_vx;
      double elapse = time - ts;
      double py = 0.0, vy = 0.0;
      if (vs >= cutoff)
      {
         py = (vs - 0.5 * g * elapse) * elapse;
         vy = vs - g * elapse;
      }

      // check for bounce
      if (vy < 0.0 && py < 0.0)
      { 
         // collision time
         double tc = 2.0 * vs / g;

         // update speed after bounce and time of collision
         springnumber++;
         vs *= spring;
         ts += tc;

         continue;
      }

      // print
      printf("%f,%f\n", px, py);

      // timestep
      time += dt;
   }

   return 0;
}

测试结果,参数与之前相同:

enter image description here

球不再是#34;隧道&#34;,这是正确的行为。