关于c ++:如何在opengl中旋转向量?

How to rotate a vector in opengl?

使用glm :: rotate时,我想旋转对象。

它只能在X,Y,Z箭头上旋转。

例如,Model = vec3(5,0,0)

如果我使用Model = glm :: rotate(Model,glm :: radians(180),glm :: vec3(0,1,0));

变成vec3(-5,0,0)

我想要一个API,因此我可以在vec3(0,4,0)上旋转180度,因此模型移至vec3(3,0,0)

我可以使用任何API吗?


是的,OpenGL内部使用4x4统一变换矩阵。但是glRotate API使用4个参数而不是3个:

1
2
glMatrixMode(GL_MODELVIEW);
glRotatef(angle,x,y,z);

它将围绕点(0,0,0)和轴[(0,0,0),(x,y,z)]旋转选定的矩阵角度angle [deg]。如果需要围绕特定点(x0,y0,z0)旋转,则还应该平移:

1
2
3
4
glMatrixMode(GL_MODELVIEW);
glTranslatef(+x0,+y0,+z0);
glRotatef(angle,x,y,z);
glTranslatef(-x0,-y0,-z0);

这是旧的API,但是在使用现代GL时,由于不再有矩阵堆栈,您需要自己做矩阵工作(例如,通过使用GLM)。 GLM应该具有与glRotate相同的功能,只是找到模仿它的功能(看起来像glm :: rotate大致相同)。如果不是,您仍然可以使用Rodrigues旋转公式自行进行操作。

现在,您的示例对我而言毫无意义:

1
(5,0,0) -> glm::rotate (0,1,0) -> (-5,0,0)

暗示围绕y轴旋转180度?好吧,我可以看到轴,但在任何地方都看不到角度。第二个(您所需的API)甚至更值得怀疑:

1
 (4,0,0) -> wanted API -> (3,0,0)

向量在旋转后应该具有相同的大小,这显然不是这种情况(除非您要绕(0,0,0)以外的某个点旋转(也未提及)。同样,在旋转之后,您通常会将一些大小泄漏到其他轴上,而都是零,只有在特殊情况下(旋转90度的倍数)时才为零。

显然,您忘记了重要信息,或者不知道轮换的工作方式。

现在,您想旋转X,Y,Z箭头是什么意思?想要按键旋转次数递增吗?还是在您的场景中绘制了像箭头一样的GUI,并希望选择它们并在拖动时旋转?

[Edit1]新示例

I want a API so I can rotate vec3(0,4,0) by 180 deg and result
will be vec3(3,0,0)

仅在谈论点而不是向量时才可行。因此,您需要旋转中心,旋转轴和角度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// knowns
vec3 p0 = vec3(0,4,0);  // original point
vec3 p1 = vec3(3,0,0);  // wanted point
float angle = 180.0*(M_PI/180.0); // deg->rad
// needed for rotation
vec3 center = 0.5*(p0+p1); // vec3(1.5,2.0,0.0) mid point due to angle = 180 deg
vec3 axis = cross((p1-p0),vec3(0,0,1)); // any perpendicular vector to `p1-p0` if `p1-p0` is parallel to (0,0,1) then use `(0,1,0)` instead
// construct transform matrix
mat4 m =GLM::identity(); // unit matrix
m = GLM::translate(m,+center);
m = GLM::rotate(m,angle,axis);
m = GLM::translate(m,-center); // here m should be your rotation matrix
// use transform matrix
p1 = m*p0; // and finaly how to rotate any point p0 into p1 ... in OpenGL notation

我没有用GLM编写代码,因此可能会有一些小的差异。