【问题标题】:C++ AI Rotation IssueC++ AI 轮换问题
【发布时间】:2015-01-17 21:38:24
【问题描述】:

对于我正在制作的游戏,我想要 3 艘船,它们都将按照一系列点在地图上竞速。它工作得非常好,除了地图上的一个点,船决定逆时针旋转近 360 度,即使顺时针只需要 10 度就足够了。

计算旋转的代码:

vec2 distance = *desiredPosition - position;
float rot = atan2(distance.y, distance.x);
rot = rot * 180.f / PI + 90.f;

if (rot < angle)
{
    angle -= dAngle;
    boat->RotateImage(-dAngle);
}
if (rot > angle)
{
    angle += dAngle;
    boat->RotateImage(dAngle);
}

velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));

我如何确保它不会在那里以错误的方向旋转?


感谢 Richard Byron(以下已接受答案),问题已解决。使用点积比使用度数更好。

最终代码:

vec2 distance = desiredPosition - position;
normal = vec2(sin((angle - 90) * PI / 180.0), cos((angle - 90) * PI / 180.0) * -1);
float dir = normal.x * distance.x + normal.y * distance.y;

//turn
if (dir > 0)
{
    angle -= dAngle;
    boat->RotateImage(-dAngle);
}
if (dir < 0)
{
    angle += dAngle;
    boat->RotateImage(dAngle);
}

velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));

【问题讨论】:

  • 您的问题将是 360 度左右。如果您的 angle 是 359,但您的 rot 是 3 度,它应该向右转 4 度,而不是向左转 356 度。
  • 您需要确定每个方向(CW/CCW)所需的旋转,然后选择较小的那个。
  • 另一个旋转计算使用:vec2 distance = position - *desiredPosition;对吗?

标签: c++ rotation game-ai


【解决方案1】:

船的转弯角度应小于 180 度,无论是顺时针还是逆时针。如果它向一个方向转动超过 180 度,最好转向另一个方向。

更通用的解决方案是计算相对于船的参考系的距离矢量。

【讨论】:

  • 如何计算顺时针方向?或者我将如何编写您的其他解决方案?
  • 抱歉回复晚了。我从你的更新中看到你已经解决了这个问题。我要说的是,一旦计算了一个方向的旋转,就可以轻松计算另一个方向(例如 rot - 360)。对于另一种解决方案,您必须将原点转换为船的位置,并将轴旋转到船的角度。也许在 3D 情况下更有用(当您的游戏使用宇宙飞船而不是船时)。很高兴你解决了这个问题,干杯。
  • 其实第二段代码还是有问题,但只是偶尔。在这一点上,我只是不知道为什么了。
【解决方案2】:

更新后的代码存在一些问题。首先,应该是 rot2 = 360 - rot1; (rot1 + 360 与 rot1 的角度完全相同)。

第二个问题是您没有考虑到 1 度和 359 度几乎是同一个角度。所以如果 abs(rot1 - angle) > 180,那么在这种情况下你真的想使用 360 - abs(rot1 - angle)。出于同样的原因,您稍后与 rot 和 angle 的比较是一个问题,您需要处理在 360 以上递增和在 0 以下递减的角度。

我可以为此编写代码,但实际上有一种更简单、更快捷的方法来执行此操作。如果你取向量(desiredPosition - 位置)和与船舶当前航向成直角的向量的点积,那么你可以根据该结果的符号转动。如果不清楚如何执行此操作,请告诉我,我可以在 cmets 中对其进行扩展。

【讨论】:

  • 谢谢,我知道有一些方法可以使用点积计算它,我试过了。但是,我也无法让它正常工作。正确的计算方法是什么?
  • 与航向垂直的向量为:vec2 normal = vec2(heading.y, -heading.x);那么点积就是 float dir = normal.x * distance.x + normal.y * distance.y;然后根据 dir 的标志向左或向右转
  • 如果我理解正确的话,代码应该是这样的:pastebin.com/4PNCe1Mq 虽然它根本不起作用。
  • 点积必须在距离和航向法线之间,例如:pastebin.com/ErT8X9RV
猜你喜欢
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多