7.Vector3向量点乘

7.3D数学-Vector3向量-向量点乘


7.1 知识点

主要学习内容

计算公式

几何意义

补充知识点 调试画线

Debug类中的DrawLine静态方法 画线段

  • 画线段:在指定的起始点与结束点之间绘制一条直线。
  • 参数:前两个参数分别是起点和终点,最后一个参数是划线颜色。
Debug.DrawLine(this.transform.position, this.transform.position + this.transform.forward, Color.red);

Debug类中的DrawRay静态方法 画射线

  • 画射线:在世界坐标中绘制一条从起点到起点加方向的直线。
  • 参数:前两个参数分别是起点和方向,最后一个参数是划线颜色。
Debug.DrawRay(this.transform.position, this.transform.up, Color.blue);

注意:方向相同的划线可能重合,可能只显示某一划线

Dot静态方法 计算两个向量的点积

Vector3.Dot方法用于计算两个向量的点积。它接受两个Vector3类型的参数,表示要计算点积的两个向量。

示例代码:

Vector3 vector1 = new Vector3(1, 2, 3);
Vector3 vector2 = new Vector3(4, 5, 6);

float dotProduct = Vector3.Dot(vector1, vector2);
Debug.Log("Dot Product: " + dotProduct);//Dot Product: 32 = 1x4+2x5+3x6

通过点乘判断对象方位

// 思路:用自己的forward向量和自己和目标的位置差算出来的向量点乘判断是否大于0
// 给用自己的forward向量和目标的位置差算出来的向量划线
Debug.DrawRay(this.transform.position, this.transform.forward, Color.red);
Debug.DrawRay(this.transform.position, target.position - this.transform.position, Color.red);

// Dot静态方法 得到两个向量的点乘结果
// 两个向量的点积。
// Vector3 提供了计算点乘的方法
// 向量 a 点乘 AB 的结果
float dotResult = Vector3.Dot(this.transform.forward, target.position - this.transform.position);
if (dotResult >= 0)
{
    print("它在我前方");
}
else
{
    print("它在我后方");
}

点乘角度公式推导

通过点乘推导公式算出夹角

手动通过点乘公式计算两个向量之间的夹角的步骤如下:

  1. 使用单位向量计算点乘结果:
float dotResult = Vector3.Dot(this.transform.forward, (target.position - this.transform.position).normalized);
  1. 使用反余弦三角函数得出角度,并将弧度制转换为角度制:
print("手动算出的角度-" + Mathf.Acos(dotResult) * Mathf.Rad2Deg);

这些步骤可以用来手动计算两个向量之间的夹角,适用于需要更细致控制或理解计算过程的情况。

Angle静态方法 计算两个向量之间的夹角

Vector3.Angle静态方法用于计算两个向量之间的夹角,并以度为单位返回该角度。

  • 参数:from表示起始向量,to表示目标向量。
  • 返回值:from向量与to向量之间的夹角(以度为单位)。
Vector3 fromVector = this.transform.forward;
Vector3 toVector = target.position - this.transform.position;
float angle = Vector3.Angle(fromVector, toVector);
print("Angle静态方法算出的角度-" + angle);

注意:返回的角度范围是0到180度之间,表示两个向量之间的夹角。

总结


7.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson07_3D数学_Vector3向量_向量点乘 : MonoBehaviour
{
    public Transform target;

    void Update()
    {
        #region 补充知识点 调试画线

        ////DrawLine静态方法 画线段 
        ////在指定的起始点与结束点之间绘制一条直线。
        ////前两个参数 分别是 起点 终点 最后一个参数是划线颜色
        //Debug.DrawLine(this.transform.position, this.transform.position + this.transform.forward, Color.red);

        ////DrawRay静态方法 画射线
        ////在世界坐标中绘制一条从 start 到 start +dir 的直线。
        ////前两个参数 分别是 起点 方向 最后一个参数是划线颜色
        //Debug.DrawRay(this.transform.position, this.transform.up, Color.blue);

        ////注意:方向相同的划线可能重合,可能只显示某一划线

        #endregion

        #region 知识点一 通过点乘判断对象方位

        //思路:用自己的forward向量和自己和目标的位置差算出来的向量点乘判断是否大于0

        //给用自己的forward向量和目标的位置差算出来的向量划线
        Debug.DrawRay(this.transform.position, this.transform.forward, Color.red);
        Debug.DrawRay(this.transform.position, target.position - this.transform.position, Color.red);

        //Dot静态方法 得到两个向量的点乘结果
        //两个向量的点积。
        //Vector3 提供了计算点乘的方法
        //向量 a 点乘 AB 的结果
        float dotResult = Vector3.Dot(this.transform.forward, target.position - this.transform.position);
        if (dotResult >= 0)
        {
            print("它在我前方");
        }
        else
        {
            print("它在我后方");
        }

        #endregion

        #region 知识点二 通过点乘推导公式算出夹角

        //手动通过点乘公式算对象间夹角步骤
        //1.用单位向量算出点乘结果
        dotResult = Vector3.Dot(this.transform.forward, (target.position - this.transform.position).normalized);
        //2.用反余弦三角函数得出角度 有弧度制转成角度制度
        print("手动算出的角度-" + Mathf.Acos(dotResult) * Mathf.Rad2Deg);
         
        //Angle静态方法 得到两个向量之间的夹角
        //返回 from 与 to 之间的角度(以度为单位)。
        //Vector3中提供了 得到两个向量之间夹角的方法 
        print("Angle静态方法算出的角度-" + Vector3.Angle(this.transform.forward, target.position - this.transform.position));

        //注意:得到范围是0-180度之间
        #endregion
    }
}

7.3 练习题

当一个物体B在物体A前方45度角范围内,并且离A只有5米距离时,在控制台打印“发现入侵者”

手动算角度

if (Vector3.Distance(this.transform.position, B.transform.position) <= 5)
{
    // 第一步:算出点乘结果(方向向量)
    float dotResult = Vector3.Dot(this.transform.forward, (B.transform.position - this.transform.position).normalized);
    // 第二步:通过反余弦函数算出夹角
    if (Mathf.Acos(dotResult) * Mathf.Rad2Deg <= 22.5f)
    {
        print("手动算角度 发现入侵者");
    }
}

Angle直接算角度

// Angle直接算角度
if (Vector3.Distance(this.transform.position, B.transform.position) <= 5 &&
    Vector3.Angle(this.transform.forward, B.transform.position - this.transform.position) <= 22.5f)
{
    print("Angle直接算角度 发现入侵者");
}

这两种方法都实现了在物体B位于物体A前方45度角范围内,并且距离A不超过5米时,在控制台打印“发现入侵者”的功能。判断边界是22.5原因是45分开了两边。


7.4 练习题代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//这个脚本会挂载到物体A上
public class Lesson07_练习题 : MonoBehaviour
{
    #region 练习题一

    //当一个物体B在物体A前方45度角范围内,并且离A只有5米距离时,在控制台打印“发现入侵者”

    //得到B的位置信息 拖拽赋值
    public Transform B;

    void Update()
    {
        //手动算角度
        if (Vector3.Distance(this.transform.position, B.transform.position) <= 5)
        {
            //第一步 算出点乘结果(方向向量)
            float dotResult = Vector3.Dot(this.transform.forward, (B.transform.position - this.transform.position).normalized);
            //第二步 通过反余弦函数 算出 夹角
            if (Mathf.Acos(dotResult) * Mathf.Rad2Deg <= 22.5f)
            {
                print("手动算角度 发现入侵者");
            }
        }

        //Angle直接算角度
        if (Vector3.Distance(this.transform.position, B.transform.position) <= 5 &&
            Vector3.Angle(this.transform.forward, B.transform.position - this.transform.position) <= 22.5f)
        {
            print("Angle直接算角度 发现入侵者");
        }

    }

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏