你并没有真正进行反射......要通过主轴反射,你应该否定速度矢量的适当坐标(并纠正位置)我在你的代码中没有看到这种行为。相反,无论向上/向下方向如何,你的 y 速度都没有符号,因此你只需添加重力 acc 到它......以补救重写代码或添加yreflection
也到你的重力相关代码......你也有theta吗?我只期望第一次拍摄时的角度
see
这里是带有空气摩擦的 C++ 小例子:
//---------------------------------------------------------------------------
double pos[2],vel[2],acc[2],r; // ball
double x0,y0,x1,y1; // walls
//---------------------------------------------------------------------------
void ball_update(double dt)
{
int i;
double v,k=0.0001,g=9.81;
dt*=10.0; // time multiplier for simulation speed ...
// compute driving force/acceleration
v=sqrt((vel[0]*vel[0])+(vel[1]*vel[1])); // |vel|
acc[0]= -(k*vel[0]*v); // gravity + air friction (k*vel^2)
acc[1]=+g-(k*vel[1]*v);
// Newton/D'Alembert simulation
for (i=0;i<2;i++) vel[i]+=acc[i]*dt;
for (i=0;i<2;i++) pos[i]+=vel[i]*dt;
// colision/reflect
if (pos[0]<x0+r){ pos[0]=x0+r; vel[0]=-vel[0]; }
if (pos[0]>x1-r){ pos[0]=x1-r; vel[0]=-vel[0]; }
if (pos[1]<y0+r){ pos[1]=y0+r; vel[1]=-vel[1]; }
if (pos[1]>y1-r){ pos[1]=y1-r; vel[1]=-vel[1]; }
}
//---------------------------------------------------------------------------
void ball_init()
{
Randomize();
pos[0]=0.5*(x0+x1);
pos[1]=0.5*(y0+y1);
double a=2.0*M_PI*Random(),v=50.0;
vel[0]=v*cos(a);
vel[1]=v*sin(a);
r=20.0;
}
//---------------------------------------------------------------------------
我的坐标系是(0,0)左上角,x点向右,y点向下......
要使用它只需初始化墙壁x0,y0,x1,y1
打电话给ball_init()
然后在一些计时器调用中ball_update(dt)
并渲染球pos
和半径r
...
它是这样的:
PS.您需要调整增量时间等参数dt
、加速或添加像素比例以满足您的需求...您需要让所有单位兼容...我建议使用SI(m,m/s,m/s^2,s,N,..)所以你还需要决定像素有多大(以米为单位)