【问题标题】:How to rotate a vector in opengl?如何在opengl中旋转矢量?
【发布时间】:2018-10-14 11:39:13
【问题描述】:

当我使用 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 吗?

【问题讨论】:

  • @Spektre 你能澄清一下“在OpenGL中你使用的是四元数的glRotate”吗?它认为它使用了一个旋转矩阵,不是吗?
  • 是的,我想要一个旋转矩阵来旋转我的对象。(4,5,0) 是向量
  • 我举个例子,我想你会明白我的意思。如果在 (5,0,0) 上的一个点我使用 glm::rotate (0,1,0) 它将变为 (-5,0,0)。我需要一个 API 在 (4,0,0) 上旋转所以点变成(3,0,0)
  • @kevinsu:“我希望 API 在 (4,0,0) 上旋转,因此点变为 (3,0,0)”。但是……那不是轮换。你可以分辨,因为这两个向量的方向相同。
  • @Nicol Bolas 为什么这不是轮换? (4,0,0) 是一个向量,我在其上旋转 180 度。我的观点 (5,0,0)->(3,0,0)。我是你误解了。

标签: c++ opengl rotation glm-math 3d-model


【解决方案1】:

是的 OpenGL 在内部使用 4x4 uniform transform matrices。但是glRotate API 使用 4 个参数而不是 3 个:

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

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

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

这是旧的 API 但是在使用现代 GL 时,您需要自己做矩阵的东西(例如使用 GLM ) 因为没有矩阵堆栈了。 GLM 应该具有与glRotate 相同的功能,只需找到模仿它的功能即可(看起来glm::rotate 或多或少相同)。如果没有,您仍然可以使用 Rodrigues rotation formula 自行完成。

现在你的例子对我来说毫无意义:

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

意味着围绕y 轴旋转180 度数?好吧,我可以看到轴,但在任何地方都看不到角度。第二个(你想要的 API)更值得怀疑:

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

向量在旋转后应该具有相同的幅度,这显然不是这种情况(除非您想围绕(0,0,0) 以外的某个点旋转,这也没有提到。此外,在旋转之后,通常您会将一些幅度泄漏到其他轴你的y,z 都是零,这仅在特殊情况下是正确的(旋转 90 度的倍数时)。

很明显,您忘记提及重要信息或不知道轮换的工作原理。

现在你想在X,Y,Z 箭头上旋转是什么意思?想要在按键上进行增量旋转?或者在您的场景中呈现类似箭头的 GUI 并且想要选择它们并在它们被拖动时旋转?

[Edit1] 新示例

我想要一个 API,这样我就可以将 vec3(0,4,0) 旋转 180 deg 并得到结果 将是vec3(3,0,0)

只有当你谈论的是点而不是向量时,这才是可行的。所以你需要旋转中心和旋转轴和角度。

// 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 中编码,因此可能会有一些小的差异。

【讨论】:

  • 感谢您的回复。我编辑了我的问题,希望你知道我的意思,如果没有,我会给你更多信息
  • @kevinsu api 是相同的,您只需要计算旋转所需的纯数学内容,请参阅edit1 我还修复了翻译标志(倒置)
  • 其实我之前用过你的方法,但是不行。因为在3D视图中平移或旋转时,它会旋转或平移相机。
  • @kevinsu 为什么?仅当您使用相机矩阵时才旋转平移相机......如果您在 MODELVIEW 矩阵上使用它,那么您需要在正确的代码位置应用它,其中变换顺序将叠加到您的模型而不是相机更容易在内部有 2 个单独的矩阵,如 Camera Frame and Object Frame 并使用相乘进行渲染,但对于像这样的内部计算,请使用您的单独矩阵....请参阅 4x4 统一矩阵链接中的最后 3 个链接,有这样的示例...跨度>
  • 上帝,我知道该怎么做。非常感谢。我会给你接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
  • 2012-08-08
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多