一步步教你为网站开发android客户端,wordpress 调用page,wordpress 全局播放器,西宁市网站建设公司目录 一、什么是四元数
二、和欧拉角的关联以及为什么会出现四元数
三、四元数的基本组成
Unity中的表示#xff1a;
四、四元数Quaternion这个类中具有的属性和方法
常用属性
核心方法
五、四元数之间的计算
1. 叉乘#xff08;组合旋转#xff09;
2. 点积#…目录 一、什么是四元数
二、和欧拉角的关联以及为什么会出现四元数
三、四元数的基本组成
Unity中的表示
四、四元数Quaternion这个类中具有的属性和方法
常用属性
核心方法
五、四元数之间的计算
1. 叉乘组合旋转
2. 点积相似度
六、总结
四元数 Quaternion 属性与方法总结
详细说明
1. 属性
2. 方法
3. 运算符与静态方法 一、什么是四元数
定义 四元数Quaternion是一种数学工具用于表示三维空间中的旋转。它由四个分量组成一个实部w和三个虚部x, y, z数学表达式为 qwxiyjzk 其中 你可以想象四元数是一个“方向标记”而欧拉角是“分解成三个步骤的转动角度”。四元数通过一种紧凑的数学形式直接描述方向避免了欧拉角的分步旋转可能导致的万向节死锁问题。
Unity中的应用 在Unity中所有Transform组件的旋转底层均由四元数实现。虽然开发者通常通过欧拉角如Inspector面板中的Rotation调整物体朝向但Unity会自动将其转换为四元数存储。
二、和欧拉角的关联以及为什么会出现四元数
欧拉角的局限性 万向节死锁Gimbal Lock当绕某一轴旋转90度时另外两个轴的旋转会重合导致丢失一个自由度。就是说当你转到90度时你想单独再沿着某一条轴进行旋转发现怎么都不可以 例如飞机俯仰90度后偏航和滚转将绕同一轴旋转无法独立控制。 插值不平滑直接对欧拉角插值会导致旋转路径不自然如抖动或突变。
四元数的优势 无万向节死锁四元数通过四维空间描述旋转避免了三维欧拉角的轴顺序问题。 平滑插值支持球面线性插值Slerp保证旋转路径的最短性和平滑性。 计算高效旋转合成和逆运算更高效适合实时计算。
关联 转换关系欧拉角可通过Quaternion.Euler()转换为四元数反之通过Quaternion.eulerAngles属性获取。
三、四元数的基本组成 四元数构成 一个四元数包含一个标量和一个3D向量 [w,v]w为标量v为3D向量 [w,(x,y,z)] 对于给定的任意的一个四元数 表示3D空间中的一个旋转量 轴-角对 在3D空间中 任意旋转都可以表示 绕着某个轴旋转一个旋转角得到 注意该轴并不是空间中的xyz中轴 而是任意一个轴 对于给定旋转 假设为绕着n轴 旋转β角度 n轴为x,y,z 那么可以构成的四元数为 四元数Q [cos(β/2)sin(β/2)n] 四元数Q [cos(β/2sin(β/2)x,sin(β/2)y,sin(β/2)z] 四元数Q则表示绕着轴n旋转β度的旋转量 单位四元数 单位四元数表示没有旋转量角位移 当角度为0或者360度时 对于给定的轴都会得到单位四元数 [1,(0,0,0)]和[-1,(0,0,0)]都是单位四元数 表示没有旋转量 Unity中的表示 Quaternion q new Quaternion(x, y, z, w); // 注意Unity的构造函数参数顺序为(x, y, z, w) 例如绕Y轴旋转90度的四元数
Quaternion rotation Quaternion.Euler(0, 90, 0);
// 等效于手动计算
float angle 90 * Mathf.Deg2Rad;
Quaternion q new Quaternion(0, Mathf.Sin(angle/2), 0, Mathf.Cos(angle/2));
四、四元数Quaternion这个类中具有的属性和方法
常用属性
属性说明identity单位四元数无旋转。eulerAngles转换为欧拉角只读。
核心方法
方法说明示例AngleAxis创建绕指定轴旋转角度的四元数。Quaternion.AngleAxis(90, Vector3.up)Euler将欧拉角转换为四元数。Quaternion.Euler(0, 90, 0)Slerp球面线性插值平滑旋转。Quaternion.Slerp(a, b, t)Lerp线性插值速度更快但路径非最短。Quaternion.Lerp(a, b, t)Inverse返回反向旋转的四元数。Quaternion.Inverse(rotation)LookRotation生成朝向某个方向的旋转。Quaternion.LookRotation(direction)
详细解释
属性
1identity单位四元数无旋转 表示“不旋转”的状态常用于初始化旋转或重置物体方向。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Start(){// 将物体旋转重置为初始状态无旋转transform.rotation Quaternion.identity;}
} 2eulerAngles将四元数转换为欧拉角 返回当前四元数对应的欧拉角只读属性常用于调试或显示直观角度。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Update(){// 实时输出物体的欧拉角Debug.Log(当前欧拉角 transform.rotation.eulerAngles);// 注意直接修改 eulerAngles 可能导致问题应通过 Quaternion.Euler() 设置// transform.eulerAngles new Vector3(0, 90, 0); // 不推荐}
}
方法
(1) AngleAxis绕指定轴旋转指定角度 创建绕某个轴旋转一定角度的四元数常用于自由轴旋转。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{public float rotateSpeed 90f; // 每秒旋转90度void Update(){// 绕Y轴旋转按每秒 rotateSpeed 度旋转float angle rotateSpeed * Time.deltaTime;Quaternion rotation Quaternion.AngleAxis(angle, Vector3.up);transform.rotation rotation * transform.rotation;}
}
(2) Euler欧拉角转四元数 将欧拉角转换为四元数避免直接操作 eulerAngles 导致的问题。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{void Start(){// 设置物体绕Y轴旋转90度Quaternion targetRotation Quaternion.Euler(0, 90, 0);transform.rotation targetRotation;}
}
(3) Slerp球面线性插值 沿球面最短路径平滑插值适合摄像机跟踪或自然旋转。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform target; // 拖入目标物体public float speed 0.5f;void Update(){// 计算目标方向Vector3 direction target.position - transform.position;Quaternion targetRotation Quaternion.LookRotation(direction);// 使用Slerp平滑旋转transform.rotation Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);}
}
//先快后慢
//A.rotation Quaternion.Slerp(A.rotation,target.rotation,Time.deltaTime);//匀速变化
//time Time.deltaTime;
//B.rotation Quaternion.Slerp(start,target.rotation,time);效果物体会平滑转向目标物体路径无抖动。
(4) Lerp线性插值 快速插值但路径非最短适合对平滑性要求不高的场景。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform target;public float speed 1f;void Update(){Quaternion targetRotation Quaternion.LookRotation(target.position - transform.position);transform.rotation Quaternion.Lerp(transform.rotation, targetRotation, speed * Time.deltaTime);}
}
(5) Inverse反向旋转 获取当前旋转的逆旋转常用于坐标系转换或相对旋转。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Transform otherObject;void Update(){// 计算当前旋转的逆旋转Quaternion inverseRotation Quaternion.Inverse(transform.rotation);// 将另一个物体的旋转设置为当前物体的逆旋转otherObject.rotation inverseRotation;}
}
效果otherObject 会始终与当前物体保持反向旋转。
(6) LookRotation朝向某个方向 使物体正面朝向指定方向常用于控制角色或摄像机。
using UnityEngine;public class QuaternionExample : MonoBehaviour
{public Vector3 targetDirection Vector3.forward; // 默认朝前void Update(){// 动态让物体朝向 targetDirection 方向Quaternion targetRotation Quaternion.LookRotation(targetDirection);transform.rotation targetRotation;}
} 效果物体正面始终指向 targetDirection可修改为鼠标或目标位置。
完整臻享版
using UnityEngine;public class QuaternionDemo : MonoBehaviour
{public Transform target;public float rotateSpeed 90f;public float slerpSpeed 0.5f;void Start(){// 初始化无旋转transform.rotation Quaternion.identity;}void Update(){// 1. AngleAxis 持续绕Y轴旋转float angle rotateSpeed * Time.deltaTime;Quaternion rotation Quaternion.AngleAxis(angle, Vector3.up);transform.rotation rotation * transform.rotation;// 2. LookRotation 朝向目标if (target ! null){Vector3 direction target.position - transform.position;Quaternion targetRot Quaternion.LookRotation(direction);transform.rotation Quaternion.Slerp(transform.rotation, targetRot, slerpSpeed * Time.deltaTime);}// 3. 输出当前欧拉角Debug.Log(当前欧拉角 transform.rotation.eulerAngles);}
}
五、四元数之间的计算
1. 叉乘组合旋转
四元数乘法表示旋转的叠加顺序为从右到左应用。 公式 注意啊不满足交换律即
Quaternion qY Quaternion.Euler(0, 90, 0); // 绕Y轴转90度
Quaternion qX Quaternion.Euler(90, 0, 0); // 绕X轴转90度// 顺序1先绕Y轴转再绕X轴转
transform.rotation qX * qY;// 顺序2先绕X轴转再绕Y轴转
transform.rotation qY * qX;
/*效果顺序1物体会先面向右侧Y轴旋转然后向上翻转X轴旋转。顺序2物体会先向上翻转X轴旋转然后面向右侧Y轴旋转。
最终朝向完全不同可通过运行代码观察。
*/
2. 点积相似度
四元数的点乘Quaternion.Dot(q1, q2)返回值的范围是 [-1, 1]表示两个旋转的相似程度 1完全相同旋转。 -1互为反向旋转。 0旋转方向正交无关。 实际应用场景 (1) 判断旋转是否完成
Quaternion targetRotation Quaternion.Euler(0, 90, 0);
float similarity Quaternion.Dot(transform.rotation, targetRotation);if (similarity 0.999f) {Debug.Log(旋转完成);
}
(2) 平滑过渡检测 在插值旋转时若相似度接近1可提前终止插值以优化性能
Quaternion current transform.rotation;
Quaternion target Quaternion.Euler(0, 90, 0);
float t Quaternion.Dot(current, target);if (t 0.99f) {transform.rotation Quaternion.Slerp(current, target, Time.deltaTime * speed);
}
(3) 反向旋转检测
Quaternion inverse Quaternion.Inverse(currentRotation);
float similarity Quaternion.Dot(currentRotation, inverse);if (similarity -0.999f) {Debug.Log(当前旋转与反向旋转对齐);
}
操作数学本质Unity中的作用典型场景乘法×旋转叠加顺序敏感组合多个旋转或转换坐标系角色转身抬头、动画叠加点乘Dot四维空间中的夹角余弦检测旋转相似度、判断旋转完成或反向插值优化、AI朝向检测、反向动作触发
综合对比
using UnityEngine;public class QuaternionOperationsDemo : MonoBehaviour
{void Start(){// 1. 验证乘法顺序Quaternion qY Quaternion.Euler(0, 90, 0);Quaternion qX Quaternion.Euler(90, 0, 0);Debug.Log(顺序1 (qX*qY): (qX * qY).eulerAngles); // 输出 (90, 90, 0)Debug.Log(顺序2 (qY*qX): (qY * qX).eulerAngles); // 输出 (90, 90, 270)// 2. 验证点乘相似度Quaternion a Quaternion.identity;Quaternion b Quaternion.Euler(0, 90, 0);Quaternion c Quaternion.Inverse(b);Debug.Log(a vs b: Quaternion.Dot(a, b)); // 约0.7不相似Debug.Log(b vs b: Quaternion.Dot(b, b)); // 1完全一致Debug.Log(b vs c: Quaternion.Dot(b, c)); // -1完全反向}
}
3. 逆运算
四元数的逆Inverse表示反向旋转。
公式
例如
Quaternion inverse Quaternion.Inverse(rotation); 这里同上不再赘述
六、总结
四元数 Quaternion 属性与方法总结
属性/方法参数返回值简单示例identity无Quaterniontransform.rotation Quaternion.identity;eulerAngles无Vector3欧拉角Vector3 angles transform.rotation.eulerAngles;AngleAxisfloat angle, Vector3 axisQuaternionQuaternion q Quaternion.AngleAxis(90, Vector3.up);Eulerfloat x, float y, float z 或 Vector3 eulerQuaternionQuaternion q Quaternion.Euler(0, 90, 0);SlerpQuaternion a, Quaternion b, float tQuaternionQuaternion.Slerp(current, target, Time.deltaTime * speed);LerpQuaternion a, Quaternion b, float tQuaternionQuaternion.Lerp(current, target, Time.deltaTime * speed);InverseQuaternion rotationQuaternionQuaternion inverse Quaternion.Inverse(transform.rotation);LookRotationVector3 forward, Vector3 upwardsVector3.up可选QuaternionQuaternion q Quaternion.LookRotation(target.position - transform.position);operator *Quaternion a, Quaternion b或 Vector3 向量Quaternion 或 Vector3Quaternion combined q1 * q2; Vector3 rotated q * Vector3.forward;DotQuaternion a, Quaternion bfloat相似度float similarity Quaternion.Dot(q1, q2);
详细说明
1. 属性
属性说明identity表示无旋转的四元数等同于 new Quaternion(0, 0, 0, 1)。eulerAngles将四元数转换为欧拉角单位为度仅用于调试不可直接修改。
2. 方法
方法说明AngleAxis绕指定轴旋转指定角度单位为度。Euler将欧拉角转换为四元数单位为度。Slerp沿球面最短路径插值适合平滑旋转如摄像机跟随。Lerp线性插值速度更快但路径可能非最短。Inverse返回反向旋转的四元数等效于逆矩阵。LookRotation生成朝向指定方向的四元数默认以 Vector3.up 为向上方向。
3. 运算符与静态方法
操作说明operator *组合两个四元数的旋转或对向量应用旋转顺序为从右到左。Dot计算两个四元数的四维点积用于判断旋转相似度1为相同-1为反向。