两向量的角度
数学原理
1、点乘公式:a·b=|a|·|b|cos<a,b> ,其中|a|和|b|表示向量的模,<a,b>表示两个向量的夹角。 即<a,b> = (a·b)/(|a|·|b|) 2、叉乘公式:c =a x b 其中a,b,c均为向量,结果向量c垂直于a,b向量所在的平面。 Unity中用Vector3.Dot()求点乘。 Vector3.Dot 点乘结果=0,两向量垂直;点乘结果>0,两向量夹角小于90°;点乘结果<0,两向量夹角大于90°。 Unity中用Vector3.Cross()求叉乘。 Vector3.Cross 叉乘返回为同时垂直于两个参数向量的向量,方向可朝上也可朝下,由两向量夹角的方向决定。 Unity中直线用向量表示,假设空间存在三个点两两组成两个向量dirA,dirB Unity存在Vector3.Angle求两向量角度的静态方法可直接调用 static function Angle (from : Vector3, to : Vector3) : float 再使用Vector3.Cross()求叉乘判断一下方向即可
Vector3 Point1 = new Vector3(1, 2.0f, 3.0f);
Vector3 Point2 = new Vector3(2, 3.0f, 4.0f);
Vector3 Point3 = new Vector3(1, 4.5f, -4.3f);
Vector3 line1 = Point2 - Point1;
Vector3 line2 = Point3 - Point2;
Debug.DrawLine(Point1, Point2, Color.green);
Debug.DrawLine(Point3, Point2, Color.red);
float angle = Vector3.Angle(line1, line2);
float dir = (Vector3.Dot(Vector3.up, Vector3.Cross(line1, line2)) < 0 ? -1 : 1);
angle *= dir;
Debug.Log("夹角为:" + angle);
效果如下:  
直线向量与GameObject的角度
法向量
直线向量与GameObject的角度计算需要使用到GameObject的法向量 在Unity中,GameObject有三个法向量
名称 | 介绍 |
---|
forward | Shorthand for writing Vector3(0, 0, 1)写Vector3(0, 0, 1)的简码,也就是向z轴。 | up | Shorthand for writing Vector3(0, 1,0)写Vector3(0, 1,0)的简码,也就是向y轴。 | right | Shorthand for writing Vector3(1,0,0)写Vector3(1,0,0)的简码,也就是向x轴。 |
使用Vector3.Angle求出直线向量与GameObject各法线的夹角 注意:直线向量与平面法线的夹角并不代表直线向量与平面的角度,须用到他们两角之和为90度这一关系求出直线向量与平面的角度 代码如下:
public GameObject Camera;
Vector3 Point1 = new Vector3(1.8f, 2.0f, 3.0f);
Vector3 Point2 = new Vector3(5.2f, 3.0f, 4.5f);
Vector3 line1 = Point2 - Point1;
Debug.Log("直线向量" + line1);
Debug.DrawLine(Point1, Point2, Color.green);
Debug.Log("相机向x轴的法向量" + Camera.transform.right);
Debug.Log("相机向y轴的法向量" + Camera.transform.up);
Debug.Log("相机向z轴的法向量" + Camera.transform.forward);
float anglex = angleByGameObjict(line1, Camera.transform.right,"x");
float angley = angleByGameObjict(line1, Camera.transform.up, "y");
float anglez = angleByGameObjict(line1, Camera.transform.forward, "z");
这里将求角度的方法定义成一个函数angleByGameObjict,实现如下
float angleByGameObjict(Vector3 v1,Vector3 v2,string axis)
{
float angle = Vector3.Angle(v1, v2);
float dir = (Vector3.Dot(Vector3.up, Vector3.Cross(v1, v2)) < 0 ? -1 : 1);
angle *= dir;
Debug.Log("直线与相机向" + axis + "轴的法向量的夹角为:" + angle);
angle = 90 - angle;
return angle;
}
效果如下: 
|