返回首页DA系统C#IDE文件同步服务屏保 今天是: 2026-05-05    "立夏"  夏季的第一个节气,表示盛夏时节的正式开始

搜索
热搜: linux 技术
Hi~登录注册
查看: 2277|回复: 0

[原创] 【原创】三维数学-四元数类详细讲解

[复制链接]
发表于 2021-9-7 12:22:16 | 显示全部楼层 |阅读模式
本帖最后由 da11 于 2021-9-7 12:24 编辑

    //注视某个物体的公开变量
    public Transform ObjVar;


    //四元数讲解
    private void OnGUI()
    {
        if (GUILayout.Button("设置物体旋转角度"))
        {
            //使用四元数旋转角度需创建以下代码(需明确旋转轴和旋转弧度)---原理性代码

            Quaternion ObjRotation = new Quaternion();   //定义Quaternion类

            //旋转轴
            Vector3 ZX = Vector3.up; //按y轴旋转

            //旋转弧度
            float RadNum = 50 * Mathf.Deg2Rad;


            //ObjRotation.x = Mathf.Sin(RadNum / 2) * ZX.x;
            //ObjRotation.y = Mathf.Sin(RadNum / 2) * ZX.y;
            //ObjRotation.z = Mathf.Sin(RadNum / 2) * ZX.z;

            //ObjRotation.w = Mathf.Cos(RadNum / 2);

            //this.transform.rotation = ObjRotation;

            //使用以下方法可以更快的使用四元数旋转物体,原理和上方的代码一致,为常用方法。
            //欧拉角转换为四元数
            //Quaternion.Euler(欧拉角(填写向量或者xyz));
            this.transform.rotation = Quaternion.Euler(0, RadNum * Mathf.Rad2Deg, 0);

            //使用以下方法可以更快的使用四元数旋转物体,原理和上方的代码一致,为常用方法。
            //------------------------1.欧拉角转换为四元数------------------------
            //Quaternion.Euler(欧拉角(填写向量或者xyz));
            //this.transform.rotation = Quaternion.Euler(0, RadNum * Mathf.Rad2Deg, 0);

            //------------------------2.四元数转换为欧拉角------------------------
            //将自身四元数赋值给->四元数类型变量fourSS
            //Quaternion fourSS = this.transform.rotation;

            //四元数类型变量fourSS调用eulerAngles方法转换为欧拉角并赋值给->向量类型变量ouLa1
            //Vector3 ouLa1 = fourSS.eulerAngles;

            //------------------------3.轴/角------------------------
            //Quaternion.AngleAxis(旋转角度, 轴向(可以是根据公式相减的一条轴向也可以是标准的xyz轴));
            //Quaternion BL1 = Quaternion.AngleAxis(50, Vector3.up); //沿y轴旋转50度的四元数
            //以上语句和Quaternion.Euler(0, 50, 0);一样,但是Quaternion.Euler适合标准化的轴,Quaternion.AngleAxis的轴向则随意很多

            //this.transform.rotation = BL2;  //并根据以上四元数旋转当前物体

            //------------------------4.z轴注视旋转------------------------
            //根据z轴旋转方向
            //注视着当前物体到ObjVar的向量可控速度旋转
            //Quaternion.LookRotation 返回的是一个旋转的结果,可以与旋转可控速度 Quaternion.Lerp 方法配合使用。transform.LookAt 方法则不能轻易的改变旋转速度!
            //当前物体指向注视物体,公式为:注视物体减去当前物体的位置向量
            //Quaternion lookFX = Quaternion.LookRotation(ObjVar.position - this.transform.position);

            //------------------------5.差值旋转------------------------
            //差值(变速)旋转:Quaternion.Lerp 方法
            //this.transform.rotation = Quaternion.Lerp(this.transform.rotation, lookFX, 0.1f);
            //实用案例:Lerp 方法永远不会到达终点,所以旋转的角度最终也不会相等目标点
            //使用 Quaternion.Angle 方法判定两个向量的角度,然后使用if判断是否小于1°,是则赋值角度旋转即可。
            //float pd1 = Quaternion.Angle(this.transform.rotation, lookFX);
            //if (pd1 < 1)
            //{
            //    this.transform.rotation = lookFX;
            //}

            //------------------------6.匀速旋转------------------------
            //匀速旋转:Quaternion.RotateTowards 方法
            //this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation, lookFX, 0.1f);

            //------------------------7.x轴注视旋转 (2D游戏重点方法)!------------------------
            //根据x轴旋转方向
            //注视着当前物体到ObjVar的向量可控速度旋转
            //瞬移旋转法:
            //this.transform.right = ObjVar.position - this.transform.position;

            //变速旋转
            //Quaternion FX = Quaternion.FromToRotation(Vector3.right, ObjVar.position - this.transform.position);
            //this.transform.rotation = Quaternion.Lerp(this.transform.rotation, FX, 0.1f);



        }

        //以下为没有万向结死锁的通用旋转方法
        if (GUILayout.RepeatButton("按反x轴旋转"))
        {
            this.transform.rotation *= Quaternion.Euler(-1, 0, 0);
            //其实this.transform.Rotate(-1, 0, 0); 是和上面的语句一样的,以下同。

        }

        if (GUILayout.RepeatButton("按x轴旋转"))
        {
            this.transform.rotation *= Quaternion.Euler(-Vector3.left);
        }

        if (GUILayout.RepeatButton("按y轴旋转"))
        {
            //Vector3.up等于欧拉角的(0,1,0);
            this.transform.rotation *= Quaternion.Euler(Vector3.up);
        }

        if (GUILayout.RepeatButton("按z轴旋转"))
        {
            //Vector3.forward等于欧拉角的(0,0,1);
            this.transform.rotation *= Quaternion.Euler(Vector3.forward);
        }

        if (GUILayout.RepeatButton("设置物体旋转默认值"))
        {
            this.transform.rotation = Quaternion.Euler(0,0,0);
        }

        if (GUILayout.RepeatButton("计算右前方10米处坐标位置"))
        {
            float DistanceLocalPointVarNum = 10; //定义并赋值远端距离变量

            Vector3 DistanceLocalPoint = new Vector3(0,0,DistanceLocalPointVarNum);  //定义远端的三维向量位置

            Vector3 LocalPoint = this.transform.position;  //定义本地位置

            //计算本地旋转四元数 与 以Y轴为圆心,旋转30度的欧拉度四元数相乘,后乘以 本地坐标加上远端位置坐标,即可达到计算右前方10米处坐标位置的目的,无论物体怎么旋转,对应的都是右前方10米处坐标位置!!
            DistanceLocalPoint = (this.transform.rotation * Quaternion.Euler(0, 30, 0)) * (LocalPoint + DistanceLocalPoint);

            //将位置使用Debug.DrawLine调试画出来
            Debug.DrawLine(LocalPoint, DistanceLocalPoint);
        }

        if (GUILayout.RepeatButton("当前物体注视某个物体的方向旋转"))
        {
            //注视着当前物体到ObjVar的向量可控速度旋转
            //Quaternion.LookRotation 返回的是一个旋转的结果,可以与旋转可控速度 Quaternion.Lerp 方法配合使用。transform.LookAt 方法则不能轻易的改变旋转速度!
            Quaternion lookFX = Quaternion.LookRotation(ObjVar.position - this.transform.position);

            //变速旋转:Quaternion.Lerp 方法
            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, lookFX, 0.1f);
            //实用案例:Lerp 方法永远不会到达终点,所以旋转的角度最终也不会相等目标点
            //使用 Quaternion.Angle 方法判定两个向量的角度,然后使用if判断是否小于1°,是则赋值角度旋转即可。
            float pd1 = Quaternion.Angle(this.transform.rotation, lookFX);
            if (pd1 < 1)
            {
                this.transform.rotation = lookFX;
            }



            //匀速旋转:Quaternion.RotateTowards 方法
            //this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation, lookFX, 0.1f);  


        }


    }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
 楼主| 发表于 2021-9-7 12:25:38 | 显示全部楼层
附上联动帖子--三维数学-欧拉角与四元数的讲解:



回复 支持 反对

使用道具 举报

游客
回复
*滑块验证:

DA论坛飞机票来了~
快速回复 返回顶部 返回列表