/// <summary> /// 两个向量的球形插值 /// </summary> /// <param name="a">向量a</param> /// <param name="b">向量b</param> /// <param name="t">t的值在[0..1]</param> /// <returns></returns> public static Vector3RightHand Slerp(Vector3RightHand a, Vector3RightHand b, float t) { // Quaternion fromQua = Quaternion.LookRotation(from, Vector3.up); // Quaternion toQua = Quaternion.LookRotation(to, Vector3.up); // Quaternion endQua = Quaternion.Slerp(fromQua, toQua, t); // // Vector3 endDir = endQua * Vector3.forward; // endDir.Normalize(); // // float length = Mathf3d.Lerp(from.magnitude, to.magnitude, t); // return endDir.normalized * length; if (t <= 0) { return(a); } else if (t >= 1) { return(b); } Vector3RightHand v = RotateTo(a, b, Vector3RightHand.Angle(a, b) * t); //向量的长度,跟线性插值一样计算 float length = b.magnitude * t + a.magnitude * (1 - t); return(v.normalized * length); }
//static Quaternion FromToRotation(Vector3 fromDiection, Vector3 toDirection) //根据两个向量计算出旋转量,计算出来的旋转量为从fromDiection,旋转到toDirection的旋转量。 //这句话意思很明显了。就是计算旋转量。 //那么LookRotation(Vector3 forward)计算的是,Z轴旋转到forward的旋转量。 //推出:Quaternion.LookRotation(new Vector3(1,0,0)) == Quaternion.FromToRotation(Vector3.forward, new Vector3(1,0,0)); //因为前者就是计算向前向量到当前向量(1,0,0)的旋转量的,其实现过程就是后者喽。 public static QuaternionRightHand FromToRotation(Vector3RightHand v1, Vector3RightHand v2) { // fromDirection.Normalize(); // toDirection.Normalize(); // Quaternion fromQua = LookRotation(fromDirection); // Quaternion toQua = LookRotation(toDirection); // fromQua = Normalize(fromQua); // toQua = Normalize(toQua); //Vector3 fromDir = fromQua * Vector3.forward; //Vector3 toDir = toQua * Vector3.forward; //Quaternion ret = RotateTowards(fromQua, toQua, float.MaxValue); //return ret; return(QuaternionRightHand.AngleAxis(Vector3RightHand.Angle(v1, v2), Vector3RightHand.Cross(v1, v2))); }
/// <summary> /// 将向量from向向量to旋转角度angle /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="angle"></param> /// <returns></returns> static Vector3RightHand RotateTo(Vector3RightHand from, Vector3RightHand to, float angle) { //如果两向量角度为0 if (Vector3RightHand.Angle(from, to) == 0) { return(from); } //旋转轴 Vector3RightHand n = Vector3RightHand.Cross(from, to); //旋转轴规范化 n.Normalize(); //旋转矩阵 Matrix4x4RightHand rotateMatrix = new Matrix4x4RightHand(); //旋转的弧度 double radian = angle * Mathf.PI / 180; float cosAngle = (float)Mathf.Cos((float)radian); float sinAngle = (float)Mathf.Sin((float)radian); //矩阵的数据 //这里看不懂的自行科普矩阵知识 rotateMatrix.SetRow(0, new Vector4(n.x * n.x * (1 - cosAngle) + cosAngle, n.x * n.y * (1 - cosAngle) + n.z * sinAngle, n.x * n.z * (1 - cosAngle) - n.y * sinAngle, 0)); rotateMatrix.SetRow(1, new Vector4(n.x * n.y * (1 - cosAngle) - n.z * sinAngle, n.y * n.y * (1 - cosAngle) + cosAngle, n.y * n.z * (1 - cosAngle) + n.x * sinAngle, 0)); rotateMatrix.SetRow(2, new Vector4(n.x * n.z * (1 - cosAngle) + n.y * sinAngle, n.y * n.z * (1 - cosAngle) - n.x * sinAngle, n.z * n.z * (1 - cosAngle) + cosAngle, 0)); rotateMatrix.SetRow(3, new Vector4(0, 0, 0, 1)); Vector4 v = Vector3RightHand.ToVector4(from); Vector3RightHand vector = new Vector3RightHand(); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; j++) { vector[i] += v[j] * rotateMatrix[j, i]; } } return(vector); }