Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

关于3D旋转(续)

  上一篇文章中只说了3D旋转最基础的一些只是,这篇文章咱就从那些知识中扩展出一些更复杂的知识。到目前为止,我的WebGL例子中使用的都是最简单的旋转。但是今后的文章中要用到一些比较特殊的旋转,所以需要这篇文章对一些东西做说明。
  我们从视图矩阵说起吧。视图矩阵就是在操作摄像机时使用的矩阵,之前介绍WebGL摄像机操作的文章中使用的就是视图矩阵。视图矩阵中有旋转的操作,它旋转的是世界。虽然视图矩阵的工作实质上确实是在对整个世界做变换,但是世界怎么可以变换呢?直觉上是不行的,我们都知道地球是会转的,可是我们的直觉就没有告诉我们地球在转,只有借助一些参照物才能知道地球是在转的,比如昼夜更替。总之,在直觉上,世界是不允许做变换的。所以视图矩阵可以理解为在对视线方向向量做变换,这个在之前的“WebGL镜面反射”中有提到。默认的视线方向和投射矩阵有关,标准右手坐标系默认视线方向是(0,0,-1),也就是我们研究看屏幕的方向。现在的概念就完全不同了。
  我们在使用视图矩阵的时候通常会有另一种情况,比如要摄像机的视线方向变换到(x,y,z)。这时候并没有给定旋转轴和旋转角度,只是给出了目标位置。这种情况怎么办?当然,我们最终不会脱离旋转,旋转是必须的,关键是要从这向量中计算出如何旋转。这种情况其实可以理解为从默认视线方向绕轴旋转两次后得到变换后的向量。求中间的两次旋转过程可以反过来从目标位置出发旋转的默认视图的思路来,先做出这个向量在两个不同平面上的投影,由这两个投影去旋转到默认视线方向的投影上。

  这个a和b就是两次旋转的角度,旋转轴就是与旋转平面垂直的轴。这样就可以得到两个旋转矩阵了,把他们相乘就可以得到最终的旋转矩阵。而且由于我们使用的都是单位向量,很多东西可以直接得到。比如a和b的角度就没必要算出来,因为找到他们的sin和cos值更容易。是不是觉得这个方法很土?那是当然,这是最简单的方法了。没有特殊情况时它也是最实用的,但是特殊情况确实存在。比如我们的摄像机需要的不是瞬间跳到目标的位置,而是走最短距离慢慢移过去。而且未必是从默认视线方向开始的,说不定在这之前就已经做过摄像机的移动了,那怎么办?其实也不难吧,还记得上一篇文章中我一笔带过的角轴旋转方式吗?我们只要通过已知的两个向量,找出它们的旋转轴和旋转角就行了。如果有空间向量的基础一定瞬间就想到算法了。有一个向量是永远垂直于两个向量构成的平面的,那就是他们的叉积。而且如果那两个向量是单位向量的话,做完叉积之后得到的的垂直向量的长度就是他们夹角的sin值。这一下就把所有需要的参数都找到了,只要带入这些参数,角轴旋转矩阵就变成我们要找的旋转矩阵了。
  看完上面这些说明,也许你会联想到很多东西。对,普通的物体也有这样的变换形式,只不过使用的不是视线位置向量,而是图元面的法向量,计算方法是一样的。有时候可以把这个计算延伸到整个物体上,给物体引入一个“朝向”的概念。很久以前我在做魔兽地图时候就发现了,在完整3D中,单位(物体)都是有朝向的概念。
  这两篇文章的内容加起来基本上就可以完成所有的3D旋转了,其他没啥了吧?还有什么需要补充的吗?
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^