Unity点乘和叉乘的应用
2019-11-01 本文已影响0人
86a262e62b0b
一. 点乘
1. 公式:
- a · b = v1( x1, y1,z1) * v2(x2, y2,z2) = x1x2 + y1y2+z1*z2;
- a · b = |a||b|Cos(θ) ( θ[0,180] )
2. 作用:
- 如果有一个为单位向量,即可算出投影
- 如果都为单位向量,可以算出夹角
- 求出夹角后,可以根据大小判断是否位于一个物体的前面或后面
- shader灯光
二. 叉乘
1. 公式:
- a x b = v1( x1, y1, z1) * v2(x2, y2, z2) = (y1z2 - y2z1) i + (x2z1 - x1z2) j + (x1y2-x2y1) k
- c = a x b 、 a x b = -b x a 、θ[0,180] 、 模长|c| = |a||b| sin<a,b>
2. 作用:
- 物体在另外一个物体的左侧还是右侧
- | A*B | 等于A和B组成的平行四边形的面积。
- shader灯光
三. 代码
1. 核心代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/**
参考:https://blog.csdn.net/bobo553443/article/details/79615454
点乘:
v1( x1, y1,z1) * v2(x2, y2,z2) = x1*x2 + y1*y2+z1*z2;
a · b = |a||b|Cos(θ) θ[0,180]
叉乘:
v1( x1, y1,z1) * v2(x2, y2, z2) = (y1*z2 - y2*z1)i + (x2*z1 - x1*z2)j + (x1*y2-x2*y1)k
c = a x b 、 a x b = -b x a 、θ[0,180] 、 模长|c| = |a||b| sin<a,b>
*/
public class RelativePosition
{
#region 两个基本方法
//得到两向量在空间中的角度[0,180],不含方向。
public static float GetAngle_Base(Vector3 VectorA, Vector3 VectorB)
{
/**
点乘:a · b = |a||b|Cos(θ) θ[0,180]
将两个向量当作单位向量
得到弧度,然后转换为角度
*/
return Mathf.Acos(Vector3.Dot(VectorA.normalized, VectorB.normalized)) * Mathf.Rad2Deg;
}
/* c = a * b
* a * b = -b * a
* |c| = |a||b| sin<a,b>
* θ[0,180]
*/
//注意,在数学中为右手法则,在unity中为左手法则
//此处,无论以哪个平面为参考,只要y轴方向值为正,那么B就在A的右边
public static bool BIsOnARight_Base(Vector3 A, Vector3 B)
{
//叉乘:
Vector3 c = Vector3.Cross(A, B);
if (c.y > 0) //B在A右边
{
return true;
}
else if (c.y > 0) //B在A左边
{
return false;
}
else //c.y == 0 , AB方向相同
{
return false;
}
}
#endregion
#region 扩展
/// <summary>
/// 1. A点的forward与到B点的向量,在空间中的角度[0,180],不含方向
/// 2. 通过返回的角度也可以判断B点是否在A点的前面或后面
/// </summary>
/// <param name="A">A点</param>
/// <param name="B">B点</param>
/// <returns></returns>
public static float GetAngle(Transform A, Transform B)
{
return GetAngle_Base(A.forward,B.position - A.position);
}
/// <summary>
/// B点是否在A点的右边?
/// </summary>
/// <param name="A">A点</param>
/// <param name="B">B点</param>
/// <returns></returns>
public static bool BIsOnARight(Transform A, Transform B)
{
return BIsOnARight_Base(A.forward, B.position - A.position);
}
#endregion
}
2.调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPosition : MonoBehaviour
{
public Transform A;
public Transform B;
private void Update()
{
Debug.Log(RelativePosition.BIsOnARight(A, B));
Debug.Log(RelativePosition.GetAngle(A, B));
}
}