我在工作应用程序上工作的时间太长了......而且很久以前就毕业了:)最近我一直在编写一个使用C的小型机器人模拟(虽然这个问题比C更算数学/算法)我有两个单位(坦克机器人)从比赛场地的X和Y坐标开始 .
现在,面板上有按键可以旋转它们,还有一个按键可以向前移动它们 . 我现在面临着从旋转度到下一个X,Y坐标转换到笛卡尔游戏区域的轻微脑崩溃 .
由于HW的限制,只有固定点可用于实际运动,但计算可以通过浮点值来完成 .
我刚刚从内存中编写了以下代码:
/* Recalculate to radians */
int radians;
/* Use sin and cos to get a vector (new x and y coords). Translate from polar to
cartesian coordinates */
radians = (int) _tanks[0].rotationAngle * (M_PI / 180);
_tanks[0].x += _tanks[0].speed * cos(radians);
_tanks[0].y += _tanks[0].speed * sin(radians);
radians = (int) _tanks[1].rotationAngle * (M_PI / 180);
_tanks[1].x += _tanks[1].speed * cos(radians);
_tanks[1].y += _tanks[1].speed * sin(radians);
不幸的是,在编写纯商业软件这些年后,似乎我的大脑在极坐标数学和几何上并没有真正刷新,所以它似乎无法按预期工作 .
例如,如果rotationAngle是180,那么下一个x / y就在左边,导致机器人翻倒:)
我想要的是一个与旧的Micro Machines游戏类似的运动方案,如果你还记得下一个点在物体面对面的位置,那么它会移动(速度)那里的步数 .
有人可以建议我在哪里错了...
另外,如果在C语言中使用更简单的方法比我刚刚编写的纯数学尝试(严重的那样),请给我一个提示 .
编辑:
试图添加:
float radians;
radians = (45 - _tanks[0].rotationAngle) * (M_PI / 180);
_tanks[0].x += (int) (_tanks[0].speed * cos(radians));
_tanks[0].y += (int) (_tanks[0].speed * sin(radians));
根据下面的答案,0度确实是正Y轴 . 但这也给出了不正确的结果 . 现在180度起点的移动向左移动 . 在180度应沿负Y轴移动 .
更多代码:
初始_tank结构 -
tanks[0].acc = 0;
tanks[0].dec = 0;
tanks[0].rotationAngle = 180;
tanks[0].speed = 0;
tanks[0].x = 400;
tanks[0].y = 150;
tanks[0].turretRotationAngle = 180;
旋转度只是一个数字(固定整数),我根据圆圈@ 360度包裹它,就像这样 -
switch(direction) {
case 0:
tank->rotationAngle -= degrees;
if(tank->rotationAngle < 1) {
tank->rotationAngle = 360;
}
break;
case 1:
tank->rotationAngle += degrees;
if(tank->rotationAngle > 360) {
tank->rotationAngle = 0;
}
break;
}
顺时针旋转一键,逆时针旋转一键 .
旋转工作,但运动没有,如上所述......
调试运行结果:
初始状态(由于0速度没有移动) -
radians = -2.3561945
x = 400
y = 150
speed = 0
移动后(速度> 0) -
radians = -2.3561945 (the same since i only press the move button)
x = 399
y = 149
speed = 2
这看起来很奇怪 . 如果旋转距离初始原点180度,X坐标根本不应该改变?只有Y应该改变,而相反的方向 . 我会将变化转换为如果速度为2,矢量长度应为2,那么变化将是对象面向的方向的2步,因此y = y 2和x = x 0对象的180度旋转?
我觉得我到了那里:)
进一步编辑:
如果我这样做,似乎沿着我需要的游戏场几乎是正确的:
radians = (_tanks[0].rotationAngle - 90) * (M_PI / 180);
注意-90 ...
当速度降低时,似乎仍然出现故障,但至少它会向正确的方向移动 .
2 回答
是的,这就是你的代码所做的:你的代码是正确的,除了上面提到的
int radians
问题,前提是0°是正x轴,90°是正y轴,180°是负x -axis,270°(或-90°)是负y轴 .我猜这相反,你想要0°成为正y轴吗?并且 - 你想要90°是正x轴(所以你的角度围绕圆顺时针顺时针进行),还是负x轴(所以它们逆时针进行)?对于前一个(顺时针)情况,只需将
_tanks[...].rotationAngle
更改为(90 - _tanks[...].rotationAngle)
(在45°线附近为"flip");对于后者(逆时针)的情况,只需将其更改为(_tanks[...].rotationAngle + 90)
(至"rotate",它关于原点90°) .@ruakh和@ user3386109很好地讨论了角度单位和阶段的问题 .
另外,对于“在C中执行此操作的更平滑方式”,还要考虑:
round()
,否则代码会引入偏差 . (假设_tanks[1].x
是某个整数)float
而不是double
作为额外的精度,不需要更长的计算时间 .int
缩放的正弦和余弦值一起使用,而不是所有浮点数学 .