1 定义
可知,点积得到的是一个标量,这个标量代表什么呢?
2 几何意义
如果
b
?
\vec{b}
b
为单位向量,则表示向量
a
?
\vec{a}
a
在向量
b
?
\vec{b}
b
上的投影长度。
3 向量a·向量b = xaxb+yayb+zazb
上面这公式是怎么来的? 设 根据余弦定理有 所以
4 应用案例
4.1 求两向量的夹角
已知向量 根据点积的定义,则有 当然,这个方法Unity已经帮我封装好了,咱们要求两个向量的夹角,直接用Vector3.Angle这个方法就好。Vector3.Angle的源码如下,可以看到其内部其实就是实现了上面这个公式。
public static float Angle(Vector3 from, Vector3 to)
{
float num = (float) Math.Sqrt((double) from.sqrMagnitude * (double) to.sqrMagnitude);
if ((double) num < 1.00000000362749E-15)
return 0.0f;
return (float) Math.Acos((double) Mathf.Clamp(Vector3.Dot(from, to) / num, -1f, 1f)) * 57.29578f;
}
4.2 判断两向量是否垂直
两向量垂直时,两者夹角为90°,而cos90° = 0,故
a
?
\vec{a}
a
·
b
?
\vec{b}
b
=0。 换句话说,只要
a
?
\vec{a}
a
和
b
?
\vec{b}
b
均不为空向量,只要
a
?
\vec{a}
a
·
b
?
\vec{b}
b
=0,就说明两向量垂直。
4.3 判断NPC是否在攻击范围内
假设玩家的攻击范围为左右各60°,最大攻击半径为10。设玩家的位置为A(xa , ya, za),怪兽的位置为B(xb, yb, zb),判断怪兽是否在人的攻击范围内? 很简单,先判断两者的距离是否小于10,若大于则不在攻击范围内。 再判断
A
B
?
\vec{AB}
AB
与玩家前方的夹角是否小于30°,若大于则不在攻击范围内,若小于等于则在攻击范围内。 代码也很简单,两者的距离可通过Vector3.Distance求得,
A
B
?
\vec{AB}
AB
与玩家前方的夹角通过Vector3.Angle求得,代码如下。
public bool IsInView(Vector3 targetPos)
{
Vector3 selfPos = m_GameObject.transform.position;
if (Vector3.Distance(selfPos, targetPos) > 10f)
return false;
Vector3 loorDir = targetPos - selfPos;
if (Vector3.Angle(loorDir, m_GameObject.transform.forward) < 30f)
return true;
return false;
}
然后在Unity中测试一下。可以看到,咱们的分析是正确的。
4.4 已知入射光线和表面法线求反射光线
如图,已知入射光线
A
O
?
\vec{AO}
AO
和表面法线
n
?
\vec{n}
n
(假定为单位向量),求反射光线
O
B
?
\vec{OB}
OB
。 直接看计算过程。 又 上面这公式怎么来的?还记得点积的几何意义吗?
如果
b
?
\vec{b}
b
为单位向量,则表示向量
a
?
\vec{a}
a
在向量
b
?
\vec{b}
b
上的投影长度。
这里的
O
P
?
\vec{OP}
OP
的长度不正好是
O
A
?
\vec{OA}
OA
在单位向量
n
?
\vec{n}
n
上的投影长度么。
O
P
?
\vec{OP}
OP
的长度求到后,再乘以它的方向
n
?
\vec{n}
n
,咱们就求到
O
P
?
\vec{OP}
OP
了。 完整的推导如下。 代码如下:
private Vector3 CalcReflectDir(Vector3 lightDir, Vector3 normalDir)
{
return lightDir - 2 * Vector3.Dot(lightDir, normalDir) * normalDir;
}
在Unity中验证一下。
5 项目
链接:https://pan.baidu.com/s/1Sv7CCrnh88MEvB6evW-rQg 提取码:t4ix 博主本文博客链接。
|