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

GLM旋转物体出现偏移问题:旋转时位移但分解显示原点如何解决?

解决GLM旋转物体时出现偏移的问题

这种情况我之前做3D项目时也碰到过,核心原因就是矩阵变换的顺序搞反了——GLM用的是列主序矩阵,变换的实际应用顺序和你写代码的逻辑顺序是反过来的,搞混了就会出现“明明想绕自身旋转,结果却像绕世界原点转圈”的错觉。

问题出在哪?

你现在的代码应该是先平移到目标位置,再做旋转(或者逐步构建模型矩阵时把旋转乘在了平移之后),比如:

// 错误顺序:先平移,再旋转
glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f));
Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f));

这时候模型矩阵是旋转矩阵 × 平移矩阵,顶点变换的顺序是先平移到目标位置,再绕世界原点旋转,物体自然会绕着世界原点画圈,看起来就像是位置“变高”了。而你分解平移数据时,可能只是提取了原始的平移分量,但实际上矩阵里的平移部分已经被旋转矩阵修改了,所以才会显示原点(或者你的分解方式没考虑矩阵乘法的影响)。

正确的做法:先旋转,再平移

要让物体绕自身中心旋转,再移动到目标位置,必须保证平移矩阵乘在旋转矩阵的左边,这样顶点会先完成旋转(绕自身原点),再被平移到目标位置。

两种实现方式:

  1. 直接组合矩阵
// 先创建旋转矩阵(绕自身X轴转15度)
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f));
// 创建平移矩阵(移到目标位置)
glm::mat4 translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f));
// 模型矩阵 = 平移 × 旋转(关键!顺序不能反)
glm::mat4 Model = translation * rotation;
  1. 逐步构建时调整乘法顺序
    如果你习惯逐步添加变换,要把新的变换矩阵乘在左边:
glm::mat4 Model = glm::mat4(1.0f);
// 先添加旋转(此时Model是旋转矩阵)
Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f));
// 再把平移矩阵乘在左边,保证先旋转后平移
Model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 5.0f, 0.0f)) * Model;

额外提醒:物体枢轴点的问题

如果你的模型自身的中心不在原点(比如模型的几何中心在(0,2,0)),那还要先把模型移到原点,旋转后再移回中心,最后平移到目标位置:

glm::mat4 Model = glm::mat4(1.0f);
// 1. 把模型中心移到世界原点
Model = glm::translate(Model, glm::vec3(0.0f, -2.0f, 0.0f));
// 2. 绕自身中心旋转
Model = glm::rotate(Model, glm::radians(15.f), glm::vec3(1.0f, 0.0f, 0.0f));
// 3. 移回模型中心 + 平移到目标位置
Model = glm::translate(Model, glm::vec3(0.0f, 2.0f + 5.0f, 0.0f));

按照这个顺序调整后,旋转就只会绕物体自身中心进行,不会出现奇怪的偏移了。

内容的提问来源于stack exchange,提问作者Bjoern Meier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:54:52