我需要在绘图区域内移动对象。物体随机移动,每当它撞到墙壁时,它就会产生 pi/2 的弹跳。 (就像“乒乓球”游戏中的球)
这很容易使用两个递增的“dx”和“dy”,当它与限制发生冲突时,我只需更改正确的符号。但是在这个上,我的物体通过 vcos(theta) = x 和 vsin(theta) = y 移动。当它撞到墙上时,我需要 theta 在其自身上加上 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度)
最佳答案
你的逻辑似乎不对。垂直碰撞球速度应从垂直轴反射(reflect),水平碰撞球速度应从 hor 反射(reflect)。轴:
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;
关于c++ - 弹跳物体的三角函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34802148/