点乘和叉乘在unity中有广泛的应用:结论点乘判断角度,叉乘判断朝向方位。
点乘:结果为一个常数
又称"点积","数量积”,“内积”(Dot Product, 用*)
对于向量 A = (x1, y1, z1) ,向量 B = (x2, y2, z2),
则向量A点乘向量 B:
A·B = x1 * x2 + y1 * y2 + z1 * z2
同时有
A·B = |A||B|Cosθ
由以上两公式可见,向量的点乘结果为一个标量,即一个数值。
因为夹角θ<=180°,所以配合余弦曲线可以直观地判断出:
当向量 A·B > 0 时,θ < 90° ;
当向量 A·B < 0 时,θ > 90° ;
当向量 A·B = 0 时,θ = 90° ;
向量点乘符合乘法交换律,即:A·B = B·A
Unity项目应用:
1.根据点乘计算两个向量的夹角。θ = arccos(A·B / |A||B|)
2.根据点乘的正负值,得到夹角大小范围,>0,则夹角(0,90)<0,则夹角(90,180),可以利用这点判断一个多边形是面向摄像机还是背向摄像机。
3.根据点乘的大小,得到向量的投影长度,反应了向量的长度关系。
4.利用点积可判断一个多边形是否面向摄像机还是背向摄像机。向量的点积与它们夹角的余弦成正比,因此在聚光灯的效果计算中,可以根据点积来得到光照效果,如果点积越大,说明夹角越小,则物理离光照的轴线越近,光照越强。计算机图形学常用来进行方向性判断,如两矢量点积大于0,则它们的方向朝向相近;如果小于0,则方向相反。
叉乘:结果为一个向量
(又称"叉积",“向量积”,“外积”)(cross product,用x)
定义:C = A x B,其中A B C 均为向量
几何意义是:得到一个与这两个向量都垂直的向量,这个向量的模是以两个向量为边的平行四边形的面积。AxB = |A||B|Sinθ,这个值即就是垂直于A和B组成的平面的向量C的模长!
如果是二维计算:v1( x1, y1)x v2( x2, y2)= x1 * y2 - x2 * y1
v1和v2向量的叉乘运算:相应元素的乘积的和:v1( x1, y1,z1) x v2(x2, y2, z2) = (y1z2 - y2z1)i+(x2z1 - x1z2)j+(x1y2-x2y1)k;
利用三阶行列式计算
|i j k|
|x1 y1 z1|
|x2 y2 z2|
性质1:c⊥a,
c⊥b,即向量c与向量a,b所在平面垂直
性质2:模长|c| = |a||b| sin
性质3:(数学上)满足右手法则, a x b = -b x a,所以我们可以使用叉乘的正负值来判断a,b的相对位置,即b是处于a的顺时针还是逆时针方向。
叉乘的右手定则是用来确定叉乘积的方向的。
右手法则:右手的四指方向指向第一个矢量,屈向叉乘矢量的夹角方向(两个矢量夹角方向取小于180°的方向),那么此时大拇指方向就是叉乘所得的叉乘矢量的方向.(大拇指应与食指成九十度)(注意:Unity当中使用左手,因为Unity使用的是左手坐标系)
数学上叉乘的右手法则
叉积的作用:
叉积时一个非常重要的性质是可以通过它的符号判断两向量相互之间的顺逆时针关系:
若P×Q > 0 , 则P在Q的顺时针方向;
若P×Q < 0 , 则P在Q的逆时针方向;
若P×Q = 0 , P与Q共线,可能是同向也可能是反向;
Unity当中叉乘的左手法则,Unity项目应用:
1.根据叉乘得到a,b向量的相对位置,和顺时针或逆时针方位。
简单的说: 点乘判断角度,叉乘判断方向。
形象的说: 当一个敌人在你身后的时候,叉乘可以判断你是往左转还是往右转更好的转向敌人,点乘得到你当前的面朝向的方向和你到敌人的方向的所成的角度大小。
2.得到a,b夹角的正弦值,计算向量的夹角(0,90),可以配合点乘和Angle方法计算出含正负的方向。
3.根据叉乘大小,得到a,b向量所形成的平行四边形的面积大小,根据面积大小得到向量的相对大小。
4.如何判断一个点是否在一个矩形内?
只要判断(AE X AB ) * ( CE X CD) >= 0 就说明E在AB,CD中间夹着,同理计算另两边DA和BC就可以了。(AE X AB )>0,即说明AE在AB的顺时针方向,也就是说点E在AB的下方,同理可知点E在CD的上方。然后在判断AD和CB与点E的关系。
// 计算 |p1 p2| X |p1 p|
float GetCross(Vector2 p1, Vector2 p2, Vector2 p)
{
return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
}
//判断点p是否在p1p2p3p4的正方形内
bool IsPointInMatrix(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p)
{
var isPointIn = GetCross(p1, p2, p) * GetCross(p3, p4, p) >= 0 && GetCross(p2, p3, p) * GetCross(p4, p1, p) >= 0;
return isPointIn;
}
类似于判断一个点是否在一个三角形内?
点在三角形内?
unity中的验证看这里:unity验证