我正在尝试使用 GLFW 在 2D 空间中绕 Z 轴旋转。在搜索论坛后,我找到了一个解决方案,我实施如下:
float _FToRadians(float f)
{
return (f * C_PI) / 180.0f;
}
void _RotateVec2(fvec2 &c1, fvec2 pivot, float rotation)
{
rotation = _FToRadians(rotation);
c1.x = pivot.x + cos(rotation) * (c1.x - pivot.x) - sin(rotation) * (c1.y - pivot.y);
c1.y = pivot.y + sin(rotation) * (c1.x - pivot.x) + cos(rotation) * (c1.y - pivot.y);
}
我在这里使用
_DrawRect()
函数中的函数:
CM_GRAPHICS void _DrawRect(fvec2 start, fvec2 end, const RectOptions &options, const Color &color = CWHITE)
{
fvec2 p2 = {end.x, start.y}, p4 = {start.x, end.y};
glBegin(GL_POLYGON);
std::cout << options.rotation.x << ',' << options.rotation.y << ',' << options.rotation.z << '\n';
glColor4f(color.r, color.g, color.b, color.a);
if (options.rotation.z != 0)
{
fvec2 rc = {(start.x + end.x) / 2, (start.y + end.y) / 2};
_RotateVec2(p2, rc, options.rotation.z);
_RotateVec2(p4, rc, options.rotation.z);
_RotateVec2(start, rc, options.rotation.z);
_RotateVec2(end, rc, options.rotation.z);
}
glVertex2f(start.x, start.y);
glVertex2f(p2.x, p2.y);
glVertex2f(end.x, end.y);
glVertex2f(p4.x, p4.y);
glEnd();
}
测试后,由于某种原因,我的点围绕 x 和 y 轴旋转,并且表现不正常。我假设这段代码符合最小可重现示例的要求,其中
fvec2
是 float vec2 的结构包装器。
如有任何帮助,我们将不胜感激。
二维仿射变换的通用公式是:
T * C * R * S * -C
哪里
T:平移(物体位置)
C:中心(枢轴点)
R:旋转(绕z轴)
S:规模
如果您对平移和缩放不感兴趣(如您的示例中所示),请将它们设置为恒等,公式将简化为:
C * R * -C
3x3 平移矩阵看起来像
1 0 x
0 1 y
0 0 1
3x3 旋转矩阵(z 旋转)看起来像
c -s 0
s c 0
0 0 1
哪里
c = cos(rad)
s = sin(rad)
在传统 OpenGL 中,你会这样做
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(pivot_x, pivot_y, 0);
glRotatef(angle, 0, 0, 1); //rotate around z-axis - angle in radians
glTranslatef(-pivot_x, -pivot_y, 0);
如果您不想使用 OpenGL,那么您必须手动进行矩阵乘法,并将每个顶点坐标乘以结果变换矩阵。
提示:如果您在纸上进行计算,您会发现初始矩阵中的零取消了一些(不必要的)操作。