旋转一个正方形指向Vector2,在0度时会完全混乱



这是一个代码,用于旋转船以跟随直线。关节只是线上的Vector2。左边是0 degrees。正如你所看到的,当船从0360,或者反之亦然时,它会出现故障。

float LookAt(Vector2 joint)
{
float deltaY = rect.y - joint.Y; // Calculate Delta y
float deltaX = joint.X - rect.x; // Calculate delta x
float angle = (float)(Math.Atan2(deltaY, deltaX) * 180.0 / Math.PI) + 90; // Find angle
float amountToRotate = angle - rotation;
amountToRotate *= 0.05f;
Console.WriteLine($"Rotation: {rotation} Angle: {angle} Amount: {amountToRotate}");
return rotation + amountToRotate;
}

我使用amountToRotate变量,因为我希望旋转稍微平滑一点(在GIF上显示不好(。

https://gyazo.com/cd907763665ac41a2c8f8e5d246ab292

非常感谢您的帮助。

(如果有什么不同的话,我也会在Raylib中这样做(。

因为atan2((返回的值介于-PI和+PI之间或介于-180和+180度之间。因此,如果你的船看起来像170度,而下一个关节是179度,那么你的amountToRotate是+9度,这很好。但是,如果你的船看起来是180度,而你的关节是-180度,你的amountToRotate突然变成-360度(-180-180(,它正对着正x轴。您从amountToRotate中减去5%,并将其添加到当前旋转中(180-360*0.05=162(,这意味着船正在远离节点。

作为一个快速解决方案,您可以将角度转换为360度:

angle = (angle + 360) % 360;

但是,在正x轴的方向上,你仍然会遇到问题。更好的解决方案是计算两个矢量之间的角度并将其反转:

angleTowardsV2FromV1 = -(Math.atan2(v1.y, v1.x) - Math.atan2(v2.y, v2.x))

在你的情况下,这看起来像:

angle = (-(Math.atan2(Math.sin(rotation*Math.PI/180), Math.cos(rotation*Math.PI/180)) - Math.atan2(deltaY, deltaX)))*180/Math.PI

而且,如果你只取角度的5%,旋转就永远不会到达那里。我认为,将角度限制在+-5会更明智。例如:

const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
angle = clamp(angle, -5, +5);

而只是回报:

return rotation + angle;

我希望这能有所帮助。

最新更新