我需要在绘图区域内移动一个对象。物体随机移动,每当它撞到墙壁时它就会发出π/ 2弹跳。 (就像“乒乓球比赛”中的球一样)
这很容易使用两个增量的' dx'并且' dy',当它与极限相撞时,我会改变正确的标志。但是在这一个上,我的物体通过v cos(theta)= x和v sin(theta)= y。当它撞到墙壁时我需要增加pi / 2或减去pi / 2本身 - 所以新的theta在(x,y)上产生新的方向。
但我怀疑必须有办法做到这一点,比我的好。我可以单独检查每个屏幕限制(向上,向左,向右,向下)theta的值和增量/减量,以便产生pi / 2弹跳。但这会产生一堆if()
语句,我相信必须有一种聪明的方法来实现这一点。
我的代码是
ball.x += ball.vel * cos(ball.theta);
ball.y += ball.vel * sin(ball.theta);
if( (ball.x + ball.radius) >= window.width || (ball.x - ball.radius) <= 0
|| (ball.y + ball.radius) >= window.height || (ball.y - ball.radius) <= 0) {
ball.theta += M_PI / 2;
但这不太好用。它确实有一些反弹,但在某些时候(在4次反弹之后),它无法以我需要的方式反弹。
这是我的结构:
typedef struct {
double x;
double y;
double theta;
double vel;
double dt;
} Ball;
其中theta
表示指向方向的角度,dt
尚未使用,vel
是其速度,此时此刻是不变的。
有什么方法可以用智能方式使用三角法进行弹跳,减少cpu工作量?
编辑:将度数从度数更改为弧度。
但它仍然表现得很糟糕。它反弹就好像应该几次,并且无缘无故我现在可以看到它反弹并采取相反的轨迹。 (就像那时改变180度)
答案 0 :(得分:0)
发送到sin和cos函数的角度需要是弧度而不是度数。
答案 1 :(得分:0)
你的逻辑似乎错了。随着垂直碰撞球的速度应从垂直轴反射并与水平碰撞球的速度应从hor反射。轴:
if ((ball.x + ball.radius) >= window.width || (ball.x - ball.radius) <= 0)
ball.theta = M_PI - ball.theta;
else
if ((ball.y + ball.radius) >= window.height || (ball.y - ball.radius) <= 0)
ball.theta = - ball.theta;
答案 2 :(得分:0)
如果你总是打开PI / 2。当来自cos()的三角公式或总和
的sin()时new_dx = vel*cos(theta + PI/2) = vel * (-sin(theta)) = -old_dy;
new_dy = vel*sin(theta + PI/2) = vel * cos(theta) = old_dx;
或
new_dx = vel*cos(theta - PI/2) = vel * sin(theta) = old_dy;
new_dy = vel*sin(theta - PI/2) = vel * (-cos(theta)) = -old_dx;
但是使用绝对弹性碰撞更简单,并且根据碰撞方向改变dx或dy的符号。