我去年开始学编码。虽然不是很好。
我试着用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
我试图找出我做错了什么,但我一点也不知道。
请帮帮我!
最佳答案
这种方法的问题是Y坐标可能变成负值。一旦这样做,如果初始速度不够高,球就可能卡在表面下面,正如@RetiredNinja
的结果所证明的那样(坐标在某个不正确的地方卡在-0.049
处)。
原始代码的错误结果(不按比例),参数已修改:
球似乎是“隧道”通过地面(一些值下降到零以下)。
如何解决这个问题我们需要正确地解决碰撞,确保球反弹而不是越过表面边界。为此,让我们检查一下球在反弹发生的时间步中的行为。
当垂直速度和垂直位置都为负时发生碰撞。要查找碰撞时间和速度,请使用运动方程:
一旦我们有了碰撞速度,我们可以简单地将新的垂直速度更新为-spring * vc
(spring
应该有一个更好的名称,例如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;
}
试验结果,参数与之前相同:
球不再“隧道”,这是正确的行为。
关于c - 在c中从地面发射的弹道炮弹,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50642804/