向量

什么是向量

  • 一个数字列表,表示各个维度上的有向位移
  • 一个有大小有方向的物理量(大小即向量的模长,方向即描述空间中向量的指向)。
  • 可以表示物体的位置和方向。

    向量的大小(模)

  • 向量各分量平方和的平方根。
  • 公式:向量求模公式
  • API:float dis=vector.magnitude;
    模的平方:vector.sqrMagnitude;(因为平方根的计算耗时长,所以效率高于magnitude)

    向量的方向

  • 获取向量的方向也称"标准化向量",或"归一化向量",即获取该向量的单位向量。
  • 单位向量:大小为1的向量。
  • 公式:向量/模长
  • 几何意义:将该向量拉长或者缩短,使模长等于1.
  • API:Vector3 vectmp = vec.normalized;
    vectmp为vec的单位向量。vec.normalized():返回vec的单位向量

    向量相减

  • 等于各分量相加减
  • 公式:[x1,y1,z1] - [x2,y2,z2] = [x1-x2,y1-y2,z1-z2]
  • 几何意义:向量a与向量b相减,结果理解为以b的终点为始点,以a的终点为终点的向量,方向由b指向a。
  • 应用:计算两点之间的距离和相对方向。

    向量相加

  • 等于各分量相加和。
  • 公式:[x1,y1,z1]+[x2,y2,z2] = [x1+x2,y1+y2,z1+z2];
  • 几何意义:向量a与向量b相加,平移使b的始点与a的终点重合。结果为以a的始点为终点,以b的终点为终点的向量。
  • 应用:物体的移动。

    向量与标量的乘除

  • 乘法:该向量的各分量与标量相乘k[x,y,z] = [xk,yk,zk]
  • 除法:该向量的各分量与标量相除[x,y,z]/k = [x/k,y/k,z/k]
  • 几何意义:缩放向量长度

实例

在unity中画出向量和单位向量

打开unity项目,新建一个cube,为了方便查看可以缩小一点。给cube新建一个脚本,脚本代码如下:

public class VectorDemo : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        Demo01();
    }
    private void Demo01()
    {
        Vector3 pos = this.transform.position;
        //画出物体位置所对应的的向量
        Debug.DrawLine(Vector3.zero, pos);          
        //画出物体位置所对应的单位向量,用红线表示
        Debug.DrawLine(Vector3.zero, pos.normalized,Color.red);       
        print(pos.magnitude);       //输出向量模长
    }
}

运行效果

向量实例.gif

获取物体B指向物体A的向量(向量相减)

复制之前的cube,并给它附上画出相减向量的relDemo脚本,脚本代码如下:

public class VectorRelDemo : MonoBehaviour
{
    public GameObject cube;     //在组件面板中把另一个cube拖入这个变量
    // Update is called once per frame
    void Update()
    {
        Demo();
    }
    private void Demo()
    {
        Vector3 relativeDirection = cube.GetComponent<Transform>().position - this.GetComponent<Transform>().position;
        Debug.DrawLine(Vector3.zero,relativeDirection,Color.green);
    }
}

运行效果

相减向量实例.gif

使物体C向物体B移动(向量相加)

实现当按下A键后在物体B的坐标生成一个物体C,物体C从物体B向物体A的方向径直移动。
在上面实例的基础上,先创建一个按A生成物体C的脚本FireDemo,并赋给物体B,脚本代码如下:

public class FireDemo : MonoBehaviour
{
    public GameObject bullet;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            CreateBullet();
        }
    }

    private void CreateBullet()
    {
        bullet = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        bullet.transform.parent = this.transform;    //作为物体B的子物体
        bullet.AddComponent(System.Type.GetType("Bullet"));    //添加脚本Bullet
        bullet.transform.position = this.transform.position;
    }
}

需要让物体C从B移动到A,只需要用从原点指向C的向量加上从B指向A的向量(上面的向量相减所求得的向量),为了能看到移动过程,可以缩短b->A的向量,脚本代码如下:

public class Bullet : MonoBehaviour
{
    private Vector3 move;
    // Start is called before the first frame update
    void Start()
    {
        move = this.GetComponentInParent<VectorRelDemo>().relativeDirection;
    }

    // Update is called once per frame
    void Update()
    {
        //为了确保移动速度不与两物体间距(向量模长)相关,需要
        //先把移动向量变为单位向量,再根据后面的参数自定义速度。
        this.transform.Translate(move.normalized*0.05f);
    }
}

运行效果
向量相加实例.gif

最后修改:2020 年 01 月 06 日
如果觉得我的文章对你有用,请随意赞赏