C程序,从旋转角度获取笛卡尔坐标

C程序,从旋转角度获取笛卡尔坐标,c,math,C,Math,我已经在商业应用程序上工作太久了,似乎。。。也许是很久以前毕业的:)最近我被要求用C语言编写一个小型的机器人模拟(虽然这个问题比C语言更像数学/算法),其中我有两个单元(坦克机器人)在操场上的X和Y坐标开始 现在,面板上有用于旋转它们的键,以及用于向前移动它们的键。在笛卡尔运动场中,从旋转角度到下一个X,Y坐标的转换过程中,我现在面临着轻微的大脑崩溃 由于HW的限制,只有固定点可用于实际移动,但可以通过浮点值进行计算 我刚刚从内存中编写了以下代码: /* Recalculate to radia

我已经在商业应用程序上工作太久了,似乎。。。也许是很久以前毕业的:)最近我被要求用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位于左侧,导致机器人倾倒:)

我想要的是一个类似于旧的微型机器游戏的运动方案,如果你记得下一个点在物体所面对的前方,那么它会在那里移动(速度)步数

有人能告诉我哪里出了问题吗

另外,如果在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
    
  • 如果处理时间有限,整数查找表可以用于360
    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;