向量点积叉积( dot cross product ) 几何意义和用途

257次阅读
没有评论

有向量 a b

点积

a b = |a| |b| * cosθ

几何意义:

  1. a * b == 0,则 a ⊥ b

  2. a * b > 0,a b 同向

  3. a * b < 0,a b 异向

  4. 我们可以 normalize a 和 b,则 |a|,|b| 都为1,那么 cosθ = ab,在知道 cosθ 的情况下,我们可以求知 a 在 b 上的投射长度 |a| cosθ,b 在 a 上的投射长度 |b| * cosθ

叉积

a ^ b = |a| |b| sinθ * n (n 是根据右手法则得出的 a ^ b 方向上的单位向量,长度为1)

几何意义:

  1. a ^ b 的结果是一个向量,垂直于 a 和 b,方向由右手法则得出

  2. a ^ b != b ^ a,这是两个方向相反的平行向量

  3. |a ^ b| 是 a ^ b 向量的长度,同时也是 a 和 b 所形成的平行四边形的面积

  4. |a ^ b| == 0,则 a // b

  5. |a ^ b| = |a| |b| sinθ,所以当 normalize a 和 b 的时候,sinθ = |a ^ b|

点积(Dot Product)

点乘比较简单,是相应元素的乘积的和:

V1( x1, y1, z1)·V2(x2, y2, z2) = x1x2 + y1y2 + z1*z2;

注意结果不是一个向量,而是一个标量(Scalar),可以是负数:

A·B = |A||B|Cos(θ)

用途

θ是向量A和向量B之间的夹角。这里|A|我们称为向量A的模或范数。这样我们就和容易计算两条线的夹角:

Cos(θ) = A·B /(|A|*|B|)

点积常见的用处是:求线段在某个方向的投影长度(使B为单位向量)

计算两条线的夹角

计算点到线的距离(比如Math.sqrt(|A||A| - (A·B)(A·B)),其中B为单位向量)

叉积(Cross Product)

首先我们知道 ,对于向量u和v, u x v的结果,是得到一个既垂直于u又垂直于v的向量,假设记作n.

则有下面公式

n = u x v;

而n的方向,是由右手法则决定的。 即伸出右手,四个手指方向从u绕到v. 此时,大姆指的方向,就是n的方向。 我们通常叫做右向量。

叉积常见用途有计算点到线和点到面的距离。

点到线的距离

找出一个点和一条线间的距离是经常遇见的几何问题之一。假设给出三个点,A,B和P,你想找出点P到点A、B定出的直线间距离。第一步是找出A到B的向量AB和A到P的向量AP,现在我们用该两向量的叉积除以|AB|,这就是我们要找的的距离了。

d = (AB x AP)/|AB|

(AB X AP)/2是三角形ABC的面积,这个三角形的底是|AB|,高就是P到AB的距离。有时叉积得到的是一个负值,这种情况下距离就是上述结果的绝对值。

当我们要找点到线段的距离时,情况变得稍稍复杂一些。这时线段与点的最短距离可能是点到线段的某一端点,而不是点到直线的垂线。

例如上图(b)中点P到线段AB的最短距离应该是线段BP。我们有几种不同的方法来判断这种特殊情况。

第一种情况是计算点积AB·BP来判定两线段间夹角。如果点积大于等于零,那么表示AB到BP是在-90到90度间,也就是说P到AB的垂线在AB外,那么AB上到P距离最近的点就是B。同样,如果BA·AP大于等于零,那么点A就是距离P最近的点。如果两者均小于零,那么距离最近的点就在线段AB中的某一点。

点到面的距离

设某三维平面表达式为

ax+by+c*z+d = 0;

则其法向量即为: (a,b,c).

任意一点 p = (x1, y1, z1)到该平面的距离为:

(ax1 + by1 + cz1+d) / (aa + bb +cc)

点乘的应用:

(1) 点乘可以用来判断两个向量是否垂直,返回值为0,则垂直。(公式:abcosθ,向量夹角θ为90度,则垂直)

(2)本质上其实是判断两个向量相似的程度(2个向量夹角越小,越相似)。

(3)计算敌人在你的正方向上行走的距离,利用的是计算一个向量在另一个向量上的投影分量大小(根据点乘几何意义) (4)得到2个向量的夹角:范围[0, 180]  ,可以做游戏怪物的视角是否有查看到玩家,可以用来计算敌人是否在角色的攻击范围之内

Vector A,B; float dotValue = Vector3.Dot (A.normalized, B.normalized); float angle = Mathf.Acos(dotValue) * Mathf.Rad2Deg;   当然,更简单的方法是float  Vector3.Angle (Vector3 from, Vector3 to) 

(5)判断目标在自己的前后方位

Vector3.Dot(transform.forward, target.position)

返回值为正时,目标在自己的前方;返回值为负时,在自己的后方;返回值为0时,在自己的正左方或者正右方。

(6)模拟飞机飞行的状态,当飞机与vector3.up的点积等于0,证明飞机平行飞行;当小于0时候,证明飞机向下飞行;当大于0时候,证明飞机向上飞行。

叉乘的应用:

(1)叉乘可以用来判断两个向量是否平行或相交。返回值为0,则平行。 (2)用于求平面法线(叉乘的几何意义:absinθ) (3)计算两个物体之间形成四边形的面积(|a||b|sinθ)

(4)得到2个向量的夹角:范围[-90,90]

Vector A,B; float value = Vector3.Cross (A.normalized, B.normalized); float angle = Mathf.Asin(value) * Mathf.Rad2Deg;   (5)判断目标在自己的 左右方位        Vector3.Cross(transform.forward, target.position).y

      返回值为正时,目标在自己的右方;返回值为负时,在自己的左方;返回值为0时,在自己的正前方或者正后方。

(6)将炮管的正方向向量  与  敌人位置减去炮管位置的向量 进行叉积,得到一个向量,炮管绕此向量旋转,可以使炮管旋转至对准敌人,实现定位敌人的作用。