You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenGL中旋转向量?GLM自定义旋转轴API咨询

绕任意点旋转的实现方法(GLM)

GLM本身没有直接提供绕任意点旋转的单一API,但你可以通过平移-旋转-平移的矩阵组合来实现这个需求,这是3D变换中的标准做法。

核心原理

绕任意点P旋转的本质是把旋转操作“挪”到原点上完成,再还原回去:

  1. 先平移整个坐标系,让旋转中心P移动到原点(这样就能用glm::rotate处理绕原点的轴旋转)
  2. 执行绕目标轴的旋转操作
  3. 把坐标系平移回原来的位置,完成最终旋转

具体实现步骤

假设你要:

  • 旋转中心:glm::vec3 pivot = glm::vec3(0, 4, 0)(你指定的点)
  • 旋转轴:glm::vec3 axis = glm::vec3(0, 1, 0)(Y轴,和你之前的例子一致)
  • 旋转角度:float angle = glm::radians(180.0f)
  • 待旋转的点:glm::vec3 model = glm::vec3(5, 0, 0)

按照以下步骤构建变换矩阵并应用:

  1. 构建平移到原点的矩阵:
    glm::mat4 translateToOrigin = glm::translate(glm::mat4(1.0f), -pivot);
    
  2. 构建旋转矩阵:
    glm::mat4 rotateMat = glm::rotate(glm::mat4(1.0f), angle, axis);
    
  3. 构建平移回原位置的矩阵:
    glm::mat4 translateBack = glm::translate(glm::mat4(1.0f), pivot);
    
  4. 组合变换矩阵(注意顺序:先平移到原点,再旋转,最后平移回去):
    glm::mat4 transform = translateBack * rotateMat * translateToOrigin;
    
  5. 应用变换到你的点:
    glm::vec4 transformed = transform * glm::vec4(model, 1.0f);
    glm::vec3 result = glm::vec3(transformed.x, transformed.y, transformed.z);
    

关于你的例子的说明

按照上面的代码,用pivot=(0,4,0)旋转后,(5,0,0)会变成(-5,0,0)——这是因为旋转中心在Y轴上,绕Y轴旋转时,X-Z平面上的点到旋转中心的距离决定了旋转后的位置。

如果你想要得到(3,0,0),说明你的旋转中心应该是(4,4,0)(因为(5,0,0)和(3,0,0)的中点是(4,0,0),加上Y轴的4就是(4,4,0))。把pivot改成glm::vec3(4,4,0),运行上面的代码就能得到你想要的结果。

封装成工具函数

如果你经常需要这个操作,可以封装成一个工具函数,方便调用:

// 针对模型矩阵的版本(适合场景物体旋转)
glm::mat4 rotateAroundPivot(glm::mat4 modelMat, float angle, glm::vec3 axis, glm::vec3 pivot) {
    glm::mat4 translateToOrigin = glm::translate(glm::mat4(1.0f), -pivot);
    glm::mat4 rotateMat = glm::rotate(glm::mat4(1.0f), angle, axis);
    glm::mat4 translateBack = glm::translate(glm::mat4(1.0f), pivot);
    return translateBack * rotateMat * translateToOrigin * modelMat;
}

// 针对单个点的版本
glm::vec3 rotatePointAroundPivot(glm::vec3 point, float angle, glm::vec3 axis, glm::vec3 pivot) {
    glm::mat4 transform = glm::translate(glm::mat4(1.0f), pivot) *
                          glm::rotate(glm::mat4(1.0f), angle, axis) *
                          glm::translate(glm::mat4(1.0f), -pivot);
    return glm::vec3(transform * glm::vec4(point, 1.0f));
}

内容的提问来源于stack exchange,提问作者Kevin Su

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:57:18