unity3D物体旋转

     在3D世界里,物体有位置和姿态信息,位置很好理解,就是在空间中的坐标,有绝对坐标(position,世界坐标)和相对坐标(localPosition,相对于父物体的坐标)。

     姿态就不好理解了,描述的是物体旋转,有三个姿态,偏航,俯仰,翻滚。

     分别是物体按照x,y,z三轴旋转的结果

     旋转在unity3d中用四元数来表示,四元数的一种超复数,由一个实部和3个虚部组成,可以表示物体的旋转

     四元数 =  a+ bi + cj + dk; 满足下面公式:

     i^{2} = j^{2} = k^{2} = i*j*k = -1 

     i^{0} = j^{0} =k ^{0} = 1

    具体可以自补数学

    还有一点旋转是不满足交换律的,例如把一个长方体,先向右旋转90度,再向前旋转90度的结果,与先向前旋转90再向右旋转90度的结果是不一样的。

     说了这么多今天来做些什么呢?

     现在有如下问题:

扫描二维码关注公众号,回复: 8497250 查看本文章

        卫星在地球表面上绕地球转,卫星是有天线的,他的天线方向总是垂直于地球,不然就没法发送信号给地球,现在已知地球位置和卫星位置,把卫星旋转到合适的角度,卫星天线默认Y轴朝上

       实现如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotationaSatellite : MonoBehaviour
{
    public Transform _earth;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 v1 = _earth.position - transform.position;
        v1.Normalize();
        Vector3 v2 = transform.up;

        Vector3 vertical_v1_and_v2 = Vector3.Cross(v2, v1);
        vertical_v1_and_v2.Normalize();
        float angle = Vector3.Angle(v2, v1);

        transform.rotation = transform.rotation * Quaternion.AngleAxis(angle, vertical_v1_and_v2) ;

    }
}

     代码如上:

     解释如下:

    1、 这其实是个数学问题,首先物体有一个up方向,就是天线方向,先获取卫星的天线方向向量 即 transform.up

          再根据卫星位置和地球位置计算一个向量,该向量就是天线需要选择到的终点

    2、已知了两个向量A,B,进行归一化

          我们知道两个不重合且方向不相反的向量可以构建一个平面

    3、而通过向量的叉乘可以得到垂直于A、B两条向量的一个向量C,该向量C为旋转轴

         即A向量通过绕C轴向量旋转\Phi度就能到达B向量的位置

    4、下一步就是求需要选择的角度

         通过向量的点乘可以得到角度,在c#中有一个求角度的函数Angle

    5、有了角度和旋转轴,即可构造四元数,把原有rotation * 新构建的四元数即为旋转后的姿态。

    效果如下:

    我们发现,不管卫星如何运动,卫星天线已经于地球表面保存垂直了。

发布了69 篇原创文章 · 获赞 69 · 访问量 8430

猜你喜欢

转载自blog.csdn.net/q943520218/article/details/102941901