什么是四元数:提到四元数代表旋转,旋转轴可以是任意一轴
四元数设置物体旋转角度:四元数涉及到旋转轴:axis,旋转弧度:rad
与四元数相乘
与向量相乘
计算物体右前方30度,10米远坐标?
第一种方法:
TransformPoint :自身坐标转世界,本质就是对向量做旋转然后叠加到物体上
第二种方法:
this.transform.position=this.transform.position+Quaternion.Euler(0,30,0)
*this.transform.rotation*new vector3(0,0,10)。
对上面的式子进行分解:
54行相乘是当前物体转的时候把向量Vector3(0,10,0) 也转了。
54 56行代码vect向量是相对于世界的,所以才有58行,
58行vect通过加物体的世界位置坐标得到相对于物体的向量。
四元数应用:
创建Capsule(玩家Player)假设把玩家先放在世界原点(0,0,0)位置,球Sphere(炸弹),求切点的脚本文件挂在炸弹上。
using UnityEngine;
using System.Collections;
/// <summary>
/// 切点探测器
/// </summary>
public class TangentDetector : MonoBehaviour
{
private Vector3 leftTangent;
private Vector3 rightTangent;
private Transform playerTF;
private float radius;
private void Start()
{
GameObject playerGO = GameObject.FindWithTag("Player");
if (playerGO != null)
{
playerTF = playerGO.transform;
radius = playerGO.GetComponent<CapsuleCollider>().radius;
}
else
{
this.enabled = false;
}
}
//计算切点
public void CalaculateTangent()
{
Vector3 playerToExplosion = transform.position - playerTF.position;
Vector3 playerToExplosionRadius = playerToExplosion.normalized * radius;
float angle = Mathf.Acos(radius / playerToExplosion.magnitude) * Mathf.Rad2Deg;
rightTangent = Quaternion.Euler(0, angle, 0) * playerToExplosionRadius;
leftTangent = Quaternion.Euler(0, -angle, 0) * playerToExplosionRadius;
}
//**************测试**************
private void Update()
{
CalaculateTangent();
Debug.DrawLine(transform.position, leftTangent);
Debug.DrawLine(transform.position, rightTangent);
}
}
结果如下:
但是一旦移动玩家切点不随玩家移动:
下面我们从代码引擎来分析,玩家移动之后
7: 是世界坐标原点(0,0,0)
1:理解中的玩家到炸弹的向量: playerToExplosion
transform.position 炸弹的世界坐标位置 ; playerTF.position玩家的世界坐标位置
Vector3 playerToExplosion = transform.position - playerTF.position;
2:实际引擎中的玩家到炸弹的向量:是从世界坐标原点发出的
3:截取实际的长度为半径radius的玩家到炸弹的向量
Vector3 playerToExplosionRadius = playerToExplosion.normalized * radius;
6:把3截取的向量旋转一定的角度到待求的切点位置即旋转到4的位置,根据三角函数反余弦求出旋转角度
float angle = Mathf.Acos(radius / playerToExplosion.magnitude) * Mathf.Rad2Deg;
4:由6求的旋转角度得出playerToExplosionRadius被旋转之后的半径长向量 绿线4(相当于切点的位置)
rightTangent = Quaternion.Euler(0, angle, 0) * playerToExplosionRadius;
然而这只是相对于世界原点的,移动玩家,切点(即绿线4)不会随之移动,于是需要把绿线4移动到绿线8的地方与玩家同步
绿线8处的切点如何求呢,即用绿线4+玩家坐标向量得到红色向量5.
5:玩家自身边界,两个切点
rightTangent =playerTF .position + Quaternion.Euler(0, angle, 0) * playerToExplosionRadius;
leftTangent = playerTF.position + Quaternion.Euler(0, -angle, 0) * playerToExplosionRadius;
移动玩家,切点跟随