IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity3D C#数学系列之点积 -> 正文阅读

[游戏开发]Unity3D C#数学系列之点积


1 定义

点积的定义
可知,点积得到的是一个标量,这个标量代表什么呢?

2 几何意义

如果 b ? \vec{b} b 为单位向量,则表示向量 a ? \vec{a} a 在向量 b ? \vec{b} b 上的投影长度。
点积的几何意义

3 向量a·向量b = xaxb+yayb+zazb

上面这公式是怎么来的?

向量ab的坐标值
根据余弦定理有
余弦定理
所以
在这里插入图片描述

4 应用案例

4.1 求两向量的夹角

已知向量
向量ab的坐标值
根据点积的定义,则有
求两向量的夹角
当然,这个方法Unity已经帮我封装好了,咱们要求两个向量的夹角,直接用Vector3.Angle这个方法就好。Vector3.Angle的源码如下,可以看到其内部其实就是实现了上面这个公式。

    /// <summary>
    ///   <para>Returns the angle in degrees between from and to.</para>
    /// </summary>
    /// <param name="from">The vector from which the angular difference is measured.</param>
    /// <param name="to">The vector to which the angular difference is measured.</param>
    /// <returns>
    ///   <para>The angle in degrees between the two vectors.</para>
    /// </returns>
    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求得,代码如下。

// 判断targetPos是否在视线范围内
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
求反射光线
直接看计算过程。
反射光线计算过程01

反射光线计算过程02
上面这公式怎么来的?还记得点积的几何意义吗?

如果 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 了。
完整的推导如下。
推导过程
代码如下:

/// <summary>
/// 计算反射光线
/// </summary>
/// <param name="lightDir">入射光线</param>
/// <param name="normalDir">表面法线(单位向量)</param>
/// <returns>反射光线</returns>
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
博主本文博客链接。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:37:17  更:2021-11-29 16:37:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 7:43:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码