不能从不是原点的其他地方旋转对象
Posted
技术标签:
【中文标题】不能从不是原点的其他地方旋转对象【英文标题】:Can't rotate object from other place that isn't origin point 【发布时间】:2019-03-21 00:07:59 【问题描述】:我知道尽可能简单的方法是使用:
glTranslate(a,b,c);
glRotate(...);
glTranslate(-a,-b,-c);
但在这种情况下,我使用缓冲区来使事情更加清晰和快速,问题是我正在做同样的事情:
iMat4x4 tempModel;
iMat4x4 tempModel2;
tempModel = math::translate(tempModel, iVec3(0.5f * size.x, 0.5f * size.y, 0.0f));
model[3].z = model[3].w = 0;
model[3] = model[3] + tempModel[3];
model = math::rotate(model, rotation, iVec3(0.0f, 0.0f, 1.0f));
tempModel2 = math::translate(tempModel2, iVec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
model[3].z = model[3].w = 0;
model[3] = model[3] + tempModel2[3];
但是,当我执行object->rotation = sin(Time::WorldTime)
之类的操作时,我得到的对象是从左上角旋转的。
另外,在旋转之前将对象移动到原点的目的应该是什么,无论我更改它,旋转矩阵都没有影响,并且矩阵的第 4 列不会以任何方式与旋转矩阵相乘, 只是放在原来的位置上...
【问题讨论】:
添加平移分量不相当于乘以对应的平移矩阵,后者是正确的方法。 @meowgoesthedog 我不明白。那么预期的操作应该是什么? (不影响物体当前位置)相乘再除? 【参考方案1】:添加平移矩阵的元素不等于乘以相应的平移矩阵,后者是应用平移的正确方法。
解释
[旋转矩阵R
,平移偏移t
- 矩阵T
,模型点p
。]
直接加上平移矩阵T
相当于预乘,也就是在输出点上加上偏移量:
p --> R*p + t
( = T*R*p )
所以最后一点是:
p' = R*p - t + t = R*p
( = T*inv(T)*R )
平移矩阵及其逆矩阵(偏移-t
)相互抵消,剩下的就是围绕原点的有效旋转。
另一方面,后乘翻译矩阵相当于预先应用翻译:
p --> R*(p - t)
( = R*inv(T)*p )
所以正确的最后一点是:
p' = R*(p - t) + t
( = T*R*inv(T)*p )
请注意,有效偏移量不会抵消,因为 T
和 inv(T)
在表达式中不相邻。
正确的代码
model_final = tempModel1 * model * tempModel2;
// T * R * inv(T)
(或使用您的库中的任何一个函数以上述“常规”方式乘以矩阵)
【讨论】:
我正在尝试这个,但在矩阵乘法之后,从第 1 列到第 3 列 -1.07374e+08 和第 4 列 3 的矩阵的几乎每个参数上我得到相同的值 3.47176e+ 09.我会尝试自己做乘法。 @Aether 我确信数学是正确的,所以它可能是库函数。不要直接修改矩阵元素。还要检查构造/修饰函数是否正确初始化了所有元素——如此高的值往往是未初始化的变量。 是的,我已经在乘法的每个步骤中使用了不同的矩阵。我自己算算,看看我得到了什么 @meogoesthedog 出于某种原因让它工作了 model_final = temp1 * model * temp2;没用,model_final = temp1 * model;然后model_final = model_final * temp2;效果很好 @Aether 奇怪。可能是您的乘法运算符重载的问题。但很高兴你让它工作。以上是关于不能从不是原点的其他地方旋转对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 glm::rotate 围绕原点以外的点旋转对象?
动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转