四边形的 2D 旋转
2D rotation of a quad
我正在使用C++开发一个基本的模拟程序,我有一个使用OpenGL的渲染器。我正在屏幕上渲染在模拟中具有动态位置的四边形。我的目标是在模拟中移动时更改四边形的方向。对于每个四边形,我有一个变量 (m_Rotation) 来保存它的当前旋转,我使用三角函数计算所需的旋转并将值放入变量 (m_ProjectedRotation) 中。在渲染循环中,我使用以下代码更改运动中的方向:
if(abs(m_ProjectedRotation - m_Rotation)>5.0f)
{
if ((360.0f - m_Rotation + m_ProjectedRotation) > (m_ProjectedRotation - m_Rotation))
{
m_Rotation += 5.0f;
if (m_Rotation > 360)
{
m_Rotation = fmod(m_Rotation, 360);
}
}
else
{
m_Rotation -= 5.0f;
}
}
我希望四边形根据最近的角度旋转自己(例如,如果当前角度为 330,目标角度为 30,则四边形应增加其角度直到达到 30 而不是减小角度,因为它达到 30。因为它的旋转角度较小)。在某些情况下,我的四边形逆时针旋转,即使很艰难,顺时针旋转的旋转时间也较短,反之亦然。我相信轮换的条件:
(360.0f - m_Rotation + m_ProjectedRotation) > (m_ProjectedRotation - m_Rotation)
应该有所不同以显示所需的行为。但是,我无法弄清楚。我应该如何更新此代码以获得我想要的内容?
我相信正确的解决方案应该如下:
让我们称这两个角度为from
和to
。根据您的问题,我认为两者都是积极的。有两种情况:
- 绝对距离
|to - from|
小于 180.
这意味着行进to - from
的度数比在另一个方向上的行进要小,这就是您应该选择的方式.
在这种情况下,您应该旋转sign(to-from) * deltaRotation
,其中sign(x)
= 1 如果 x> 0,否则为 -1。要查看符号函数的需求,请查看以下 2 个示例,其中|to - from|
<180: 从 = 10,到 =- 20。 到 - 从 = 10> 0,因此您应该增加旋转。 从 = 20,到 = 10。
- 到 - 从 = -10 <0,您应该减少旋转。
|to - from|
超过180。在这种情况下,方向应该是相反的,你应该旋转- sign(to-form) * deltaRotation
,注意减号。你也可以用sign(from-to) * deltaRotation
来表达,交换from
和to
,但我把它们留作以前,为了明确起见。- 从 = 310,到 = 10。然后,到 - from = -300 <0,您应该增加旋转(形式上,-sign(to-from ) = -sign(-300) = -(-1) = 1)
- 从 = 10,到 = 310。然后,到 - from = 300> 0,您应该减少旋转(形式上,-sign(to-from) = -sign(300) = -1)
用C++编写此内容,您可以将此逻辑封装在这样的函数中:
int shorterRotationSign(float from, float to) {
if(fabs(to - from) <= 180) {
return to - from > 0 ? 1 : -1;
}
return to - from > 0 ? -1 : 1;
}
您将像这样使用:
m_Rotation += 5.0f * shorterRotationSign(m_Rotation, m_ProjectedRotation);
m_Rotation = fmod(m_Rotation + 360, 360);
最后一行的目标是归一化负角度和大于 360 的角度。
(IMO 这更像是一个数学问题,而不是关于 opengl 的问题。
我会做这样的事情:
auto diff = abs(m_ProjectedRotation - m_Rotation);
if(diff > 5.0f)
{
diff = fmod(diff, 360.0f);
auto should_rotate_forward = (diff > 180.0f) ^ (m_ProjectedRotation > m_Rotation);
auto offset = 360.0f + 5.0f * (should_rotate_forward ? 1.0f : -1.0f);
m_Rotation = fmod(m_Rotation + offset, 360.0f);
}
diff
是旋转的绝对角度。然后,通过执行diff = fmod(diff, 360.0f)
使其处于 [0; 360) 范围内。
should_rotate_forward
确定是应减小还是增加当前角度。请注意,^
是异或操作
offset
基本上是-5.0
或5.0
,具体取决于条件,但也有一些+360.0f
,例如,如果m_Rotation == 1.0
和offset == -5.0
,那么fmod(m_Rotation + offset, 360.0f)
在您想要356.0
时会-4.0
,所以你添加完整的360旋转,之后fmod
一切都是积极的,并且在[0; 360)范围内
- 四边形的 2D 旋转
- 简化代码以避免在顺时针旋转2D矩阵时出现TLE
- 2D旋转问题C Directx
- 为什么我的 2D 阵列不旋转?
- 优化2D旋转
- 顺时针旋转2D阵列
- 无法使用 opengl 正确旋转 2D 对象
- 在C 中旋转矩阵(2D阵列)45度
- 2D 旋转打开
- 将2D转换的1D阵列顺时针旋转90度
- OpenGL - 2D敌人不旋转面对玩家
- C++ 2D 如何在宇宙飞船上"stick"排气精灵并允许其相应地旋转?
- C++ 如何保持炮塔与油箱在同一轴上旋转?(2D坦克指挥官游戏)
- 使用旋转矩阵旋转纹理2d
- 旋转 2D 正方形
- 旋转长方体2d中的关节
- 是否有一个c++源/lib来解决2D Bin Packing使用矩形Bin(而不是正方形)和旋转
- 如何围绕任意点旋转一组2D形状
- 我们如何在openGL中相对于一个点(而不是原点)旋转2d中的图形
- 使用OpenGL固定功能旋转和平移2D图像