为什么旋转和方向之间有90度的差异?
Why is there a difference of 90 degrees between rotation and direction?
首先,这个问题不是我目前正在做的项目独有的,之前已经发生过好几次了。问题来了。
我有一个 Triangle
结构。 olc::vf2d
是一个包含 x 和 y 分量的向量 class。
struct Triangle
{
olc::vf2d p1 = { 0.0f, -10.0f };
olc::vf2d p2 = { -5.0f, 5.0f };
olc::vf2d p3 = { 5.0f, 5.0f };
};
我创建了一个三角形及其位置和角度。
Triangle triangle
olc::vf2d position = { 0.0f, 0.0f };
float angle = 0.0f;
现在,我旋转(并偏移)三角形:
float x1 = triangle.p1.x * cosf(angle) - triangle.p1.y * sinf(-angle) + position.x;
float y1 = triangle.p1.x * sinf(-angle) + triangle.p1.y * cosf(angle) + position.y;
float x2 = triangle.p2.x * cosf(angle) - triangle.p2.y * sinf(-angle) + position.x;
float y2 = triangle.p2.x * sinf(-angle) + triangle.p2.y * cosf(angle) + position.y;
float x3 = triangle.p3.x * cosf(angle) - triangle.p3.y * sinf(-angle) + position.x;
float y3 = triangle.p3.x * sinf(-angle) + triangle.p3.y * cosf(angle) + position.y;
当我增加每一帧的角度并绘制它时,它会旋转并按预期工作。但现在问题来了。当我尝试计算它移动的方向时,像这样:
position.x -= cosf(angle) * elapsedTime;
position.y -= sinf(-angle) * elapsedTime;
它在移动,但看起来与旋转方向偏离了 90 度。例如,它正面朝上并向右移动。
到目前为止,我总是通过使用不同的角度值来解决这个问题,即从方向计算中使用的角度中去掉 3.14159f / 2.0f 弧度
position.x -= cosf(angle - (3.14159f / 2.0f));
position.y -= sinf(-angle - (3.14159f / 2.0f));
反之亦然,这解决了问题(现在它朝着它所面对的方向移动)。
但是现在我想知道为什么会发生这种情况以及解决这个问题的正确方法,非常感谢。
有一些缺失的项目可以诊断。你必须有某种坐标系。是右手坐标系还是左手坐标系。你可以通过 X/Y 原点来确定这一点,并用拇指指向你来想象你的手在它上面。当X轴逆时针旋转时,即右手手指在可视化时弯曲的方式,正X轴向正Y轴(右手系统)移动还是向右移动负 Y 轴(左手系)。
例如,大多数代数图形是用右手系统完成的,但在监视器的原始像素上,正 Y 是 向下 而不是通常在代数中看到的 up。
运动方向应该与旋转角度无关——除非你真的想要它们耦合,这通常不是这种情况。
为运动方向和旋转角度使用两个不同的变量将使您能够在视觉和心理上将两者分离并更好地了解正在发生的事情。
现在,通常——想想代数——旋转角度是从“东”开始测量的——指向右边——是零度,“北”是 90 度——向上——等等上。
如果您想“直线向上”移动,您不是在零度方向移动,而是在 90 度方向移动-度方向。因此,如果您的旋转是零度,但希望移动像三角形点一样“直线上升”,那么您应该使用 90 度偏移来移动与旋转。
如果将旋转和运动分离,这种行为更容易理解和观察。
首先,这个问题不是我目前正在做的项目独有的,之前已经发生过好几次了。问题来了。
我有一个 Triangle
结构。 olc::vf2d
是一个包含 x 和 y 分量的向量 class。
struct Triangle
{
olc::vf2d p1 = { 0.0f, -10.0f };
olc::vf2d p2 = { -5.0f, 5.0f };
olc::vf2d p3 = { 5.0f, 5.0f };
};
我创建了一个三角形及其位置和角度。
Triangle triangle
olc::vf2d position = { 0.0f, 0.0f };
float angle = 0.0f;
现在,我旋转(并偏移)三角形:
float x1 = triangle.p1.x * cosf(angle) - triangle.p1.y * sinf(-angle) + position.x;
float y1 = triangle.p1.x * sinf(-angle) + triangle.p1.y * cosf(angle) + position.y;
float x2 = triangle.p2.x * cosf(angle) - triangle.p2.y * sinf(-angle) + position.x;
float y2 = triangle.p2.x * sinf(-angle) + triangle.p2.y * cosf(angle) + position.y;
float x3 = triangle.p3.x * cosf(angle) - triangle.p3.y * sinf(-angle) + position.x;
float y3 = triangle.p3.x * sinf(-angle) + triangle.p3.y * cosf(angle) + position.y;
当我增加每一帧的角度并绘制它时,它会旋转并按预期工作。但现在问题来了。当我尝试计算它移动的方向时,像这样:
position.x -= cosf(angle) * elapsedTime;
position.y -= sinf(-angle) * elapsedTime;
它在移动,但看起来与旋转方向偏离了 90 度。例如,它正面朝上并向右移动。
到目前为止,我总是通过使用不同的角度值来解决这个问题,即从方向计算中使用的角度中去掉 3.14159f / 2.0f 弧度
position.x -= cosf(angle - (3.14159f / 2.0f));
position.y -= sinf(-angle - (3.14159f / 2.0f));
反之亦然,这解决了问题(现在它朝着它所面对的方向移动)。
但是现在我想知道为什么会发生这种情况以及解决这个问题的正确方法,非常感谢。
有一些缺失的项目可以诊断。你必须有某种坐标系。是右手坐标系还是左手坐标系。你可以通过 X/Y 原点来确定这一点,并用拇指指向你来想象你的手在它上面。当X轴逆时针旋转时,即右手手指在可视化时弯曲的方式,正X轴向正Y轴(右手系统)移动还是向右移动负 Y 轴(左手系)。
例如,大多数代数图形是用右手系统完成的,但在监视器的原始像素上,正 Y 是 向下 而不是通常在代数中看到的 up。
运动方向应该与旋转角度无关——除非你真的想要它们耦合,这通常不是这种情况。
为运动方向和旋转角度使用两个不同的变量将使您能够在视觉和心理上将两者分离并更好地了解正在发生的事情。
现在,通常——想想代数——旋转角度是从“东”开始测量的——指向右边——是零度,“北”是 90 度——向上——等等上。
如果您想“直线向上”移动,您不是在零度方向移动,而是在 90 度方向移动-度方向。因此,如果您的旋转是零度,但希望移动像三角形点一样“直线上升”,那么您应该使用 90 度偏移来移动与旋转。
如果将旋转和运动分离,这种行为更容易理解和观察。