C程序,从旋转角度获取笛卡尔坐标
我已经在商业应用程序上工作太久了,似乎。。。也许是很久以前毕业的:)最近我被要求用C语言编写一个小型的机器人模拟(虽然这个问题比C语言更像数学/算法),其中我有两个单元(坦克机器人)在操场上的X和Y坐标开始 现在,面板上有用于旋转它们的键,以及用于向前移动它们的键。在笛卡尔运动场中,从旋转角度到下一个X,Y坐标的转换过程中,我现在面临着轻微的大脑崩溃 由于HW的限制,只有固定点可用于实际移动,但可以通过浮点值进行计算 我刚刚从内存中编写了以下代码:C程序,从旋转角度获取笛卡尔坐标,c,math,C,Math,我已经在商业应用程序上工作太久了,似乎。。。也许是很久以前毕业的:)最近我被要求用C语言编写一个小型的机器人模拟(虽然这个问题比C语言更像数学/算法),其中我有两个单元(坦克机器人)在操场上的X和Y坐标开始 现在,面板上有用于旋转它们的键,以及用于向前移动它们的键。在笛卡尔运动场中,从旋转角度到下一个X,Y坐标的转换过程中,我现在面临着轻微的大脑崩溃 由于HW的限制,只有固定点可用于实际移动,但可以通过浮点值进行计算 我刚刚从内存中编写了以下代码: /* Recalculate to radia
/* 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位于左侧,导致机器人倾倒:)
我想要的是一个类似于旧的微型机器游戏的运动方案,如果你记得下一个点在物体所面对的前方,那么它会在那里移动(速度)步数
有人能告诉我哪里出了问题吗
另外,如果在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轴移动
还有一些代码:
储罐结构的初始值-
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)——
这似乎很奇怪。如果旋转距离初始原点180度,则X坐标根本不应改变,对吗?只有Y应该改变,并且方向相反。如果速度是2,向量长度应该是2,那么在对象所面对的方向上的变化应该是2步,所以y=y+2和x=x+0,在对象上旋转180度
我觉得我快到了:)
进一步编辑:
如果我这样做的话,我在球场上所需要的几乎是正确的:
radians = (_tanks[0].rotationAngle - 90) * (M_PI / 180);
注-90
尽管如此,当速度降低时,它似乎出现了小故障,但至少它朝着正确的方向移动
例如,如果rotationAngle为180,则下一个x/y位于左侧,导致机器人倾倒:)
是的,这就是你的代码所做的:除了上面提到的int弧度
问题外,你的代码是正确的,前提是0°是正x轴,90°是正y轴,180°是负x轴,270°(或-90°)是负y轴
我猜你想要0°作为正y轴?和-您希望90°是正x轴(因此您的角度围绕圆顺时针进行),还是负x轴(因此它们逆时针进行)?对于前一种(顺时针)情况,只需将\u储罐[…]旋转角度
更改为(90-\u储罐[…]旋转角度)
(围绕45°线“翻转”);对于后一种(逆时针)情况,只需将其更改为(_tanks[…]rotationAngle+90)
(将其围绕原点“旋转”90°。和@user3386109将讨论有关角度单位和相位的问题
此外,为了“在C中实现更平滑的方式”,还应考虑:
round()
,否则代码将引入偏差。(假设\u坦克[1].x
是一个整数)
float
而不是double
,因为不需要计算时间较长的额外精度
float radians = _tanks[0].rotationAngle * (float)((M_PI / 180));
_tanks[0].x += (int) roundf(_tanks[0].speed * cosf(radians)); // note function names
int
缩放正弦和余弦值,而不是所有浮点数学
_tanks[0].x += (_tanks[0].speed * LUT_cos[_tanks[0].rotationAngle])/scale;
弧度
将是一个介于0和2PI之间的数字,即0到6.28。因此弧度必须是浮动的。旋转角度为180时,下一个x/y应该在左侧。你期待什么?cos(180度)=-1,sin(180度)=0。。。。这似乎是这段代码唯一的功能问题。你也可以考虑<代码>双< /代码>,因为<代码> MyPi是。一步代码,看看<代码>弧度< /代码>的值。正如@user3386109已经指出的那样,int
值不会很好地工作。如果无法单步执行,请添加printf()
语句以查看计算期间的值。当您知道这些值是什么时,它将帮助您找出代码没有达到预期效果的原因。尝试按如下所示进行更改,但仍无法正常工作。。。为问题添加更多代码。弧度=(_坦克[0]。旋转角度-90)*(M_π/180);这似乎给了我沿着正确的路径需要的运动,但它有点小故障时,在速度过渡。。。但它现在是沿着物体的路径按要求。。。不过,仅仅通过实验,我对这个主题的记忆非常模糊,无法记住为什么-90是正确的对齐值。@Richarderikson:对不起,我犯了一个愚蠢的错误:要“翻转”45°线,你需要从90
中减去,而不是从45
中减去!我现在已经更正了我的答案。现在我终于设法更正了最后的小故障。。。现在似乎可以工作了,只要我在我的普通快速台式电脑上对计算时间保持一定的上限,运动更新现在似乎就可以了。将此标记为已接受的答案。一旦基础工作正常,我将对此进行调查。加工
double radians = _tanks[0].rotationAngle * (M_PI / 180);
_tanks[0].x += (int) round(_tanks[0].speed * cos(radians));
float radians = _tanks[0].rotationAngle * (float)((M_PI / 180));
_tanks[0].x += (int) roundf(_tanks[0].speed * cosf(radians)); // note function names
_tanks[0].x += (_tanks[0].speed * LUT_cos[_tanks[0].rotationAngle])/scale;