opengl 先旋转后平移和先平移后旋转解惑

        我们知道,在opengl中,如果模型中点不在原点,先平移后旋转会导致模型的位移发生变化。但在项目中遇到这么一个问题,如果不知道模型中点,或者知道模型中点一定不在原点,但我们也只需要模型方向,那么我们直接将模型旋转会得到我们想要的方向吗?即如果先平移后旋转能不能得到想要的方向?

       这个地方我疑惑了很久,因为轴只有方向没有位置,默认的旋转会朝着原点计算,当时的想法是不能,想着可能整个模型会绕着原点旋转,相当于位移了,而本身形状不会变化,但结果显然是错的。

       首先做了一个demo,一个中心在原点的正方形(灰色)先绕z轴旋转30度,再沿x轴平移0.5个单位(红色),另一个正方形则相反(蓝色):

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //原图
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBegin(GL_QUADS);
    glColor3f(0.5,0.0,0.0);
    glVertex3f(-0.1,0.1,0.0);
    glVertex3f(0.1,0.1,0.0);
    glVertex3f(0.1,-0.1,0);
    glVertex3f(-0.1,-0.1,0);
    glEnd();

    //先旋转再平移
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.5,0.0,0.0);
    glRotatef(30.0,0.0,0.0,1.0);
    glBegin(GL_QUADS);
    glColor3f(0.5,0.0,0.0);
    glVertex3f(-0.1,0.1,0.0);
    glVertex3f(0.1,0.1,0.0);
    glVertex3f(0.1,-0.1,0);
    glVertex3f(-0.1,-0.1,0);
    glEnd();

   //先平移再旋转
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(30.0,0.0,0.0,1.0);
    glTranslatef(0.5,0.0,0.0);
    glBegin(GL_QUADS);
    glColor3f(0.0,0.0,0.5);
    glVertex3f(-0.1,0.1,0.0);
    glVertex3f(0.1,0.1,0.0);
    glVertex3f(0.1,-0.1,0);
    glVertex3f(-0.1,-0.1,0);
    glEnd();
    
   //坐标轴
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBegin(GL_LINES);
    glColor3f(1.0,1.0,1.0);
    glVertex3f(0.0,1.0,0.0);
    glVertex3f(0.0,-1.0,0.0);
    glVertex3f(1.0,0.0,0.0);
    glVertex3f(-1.0,0.0,0.0);
    glEnd();

 demo结果:

我们可以看到,两种行为的正方形都成功绕着z轴旋转了30度,仅是位移不同。

我们来看看为什么?

https://jingyan.baidu.com/article/414eccf617a9c66b421f0a5e.html文章中讲解了一个原因,看着很有道理,但是他这个原理起点有点歧义,他是以矩阵乘法的先后顺序来标定模型动作的先后,也就是说,在上面例子中,他认为是红色图形先做了平移,再做了旋转。我查了一些资料,这种看法也有,但主流还是本文这么认为,因为最先与顶点接触的是右边的矩阵: res=TranslateMat*RotateMat*ScaleMat*Pos,所以先后顺序应该从右向左读这个乘法。

好了,那如果先旋转再平移,从数学上怎么解释这个现象呢?

我们设旋转矩阵为R,位移为T,原位置为P,那么先旋转再平移,就可以表示为:res=R*P+T; 同理,先平移再旋转结果表达式为:res=R*(P+T)=R*P+R*T;

从表达式可以看出:最终两种结果模型本身都一样地旋转了R,但是先平移的结果位移也绕原点旋转了R。也就是说,如果只考虑模型方向,两种结果并没有差别。

最后再做一个笔记,也是以前理解的一个错误(以前我认为四元数旋转就直接以模型中点旋转了),以此为鉴。旋转有三种表达形式:旋转矩阵,欧拉角和四元数,但这三种仅是在数学上表达不一样,也有各自的优劣,但本质上还是一样的,归根到底,最终都转换到了旋转矩阵和顶点的乘法运算。

 

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值