Unity中的复合旋转

     旋转变换是三维空间变换中相对不太直观的变换方式,而且旋转后的最终结果与变换顺序密切相关,比如对于一个旋转角度(30,40,50)来说,先x轴旋转30°,再y轴旋转40°,最后绕z轴旋转50°,这只是一种变换顺序,其结果与其他变换顺序不同。

Unity中旋转API接口为Transform.Rotate(),那么对于Transform.Rotate(new Vector3(30, 40, 50))来说,究竟是选用的哪一种顺序呢?Unity官方文档中有说明,欧拉角旋转顺序为Z、X、Y,然而实际测试中发现,下面的代码的执行结果

[csharp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. transform.Rotate(new Vector3(30, 40, 50));  

与下面代码中顺序1的执行结果相同!!!

  1.         // 顺序1
  2.         transform.Rotate(new Vector3(0, 40, 0));  
  3. transform.Rotate(new Vector3(30, 0, 0));  
  4.         transform.Rotate(new Vector3(0, 0, 50));  
  5.   
  6.         // 顺序2  
  7. // transform.Rotate(new Vector3(0, 0, 50));  
  8. // transform.Rotate(new Vector3(30, 0, 0)); 
  9. // transform.Rotate(new Vector3(0, 40, 0));

为什么实际执行与官方文档说的顺序恰好相反呢?这是一个很有趣的问题。

我们仔细想想,其实旋转除了角度顺序外,还与一个重要的因素相关,那就是旋转时所用的坐标系!

对于一个给定的旋转顺序(比如官方所说的Z、X、Y)和旋转角度(α,β,r),我们其实有两种坐标系可以进行选择:

  1. 绕坐标系E下的Z轴旋转α,绕坐标系E下的Y轴旋转β,绕坐标系E下的X轴旋转r,三次旋转均使用同一坐标系;
  2. 绕坐标系E下的Z轴旋转α,绕坐标系E在绕Z轴旋转α后的新坐标系E'下的Y轴旋转β,绕坐标系E'在绕Y轴旋转β后的新坐标系E''下的X轴旋转r,三次旋转分别使用了不同的坐标系;
对于第一种情况来说,进行一次旋转时并不一起旋转当前坐标系,此坐标系我们称为惯性坐标系;第二种情况下,在旋转操作时,我们把坐标系一起转动,此坐标系我们称之为物体坐标系。

知道了这些,我们就可以探寻为什么代码编写与官方文档说明的顺序相反了。对于Transform.Rotate(new Vector3(30, 40, 50))来说,坐标轴在单个坐标轴旋转过程中不变,执行完transform.Rotate后,坐标轴才发生变化,因而一行代码合并执行采用的是上面的情况1

而分开单独执行采用的是上面的情况2

Transform.Rotate(new Vector3(0, 40, 0));

Transform.Rotate(new Vector3(30, 0, 0));

Transform.Rotate(new Vector3(0, 0, 50));


于是,问题的焦点转移到:是否情况1中的zxy顺序旋转与情况2中的yxz顺序旋转得到的结果是一样的吗?答案是的!Unity

官方文档说明的旋转顺序指的是情况1下的顺序。这也就解释清楚了上面代码执行的问题得意

为什么情况1中的zxy顺序旋转与情况2中的yxz顺序旋转得到的结果是一样的呢?可以参考这篇文章




展开阅读全文

没有更多推荐了,返回首页