【图形学】TA之路-向量

向量

向量 是一个有大小和方向的数学对象。在三维空间中,向量通常表示为 (v_x, v_y, v_z)

基本操作

  1. 加法

    a + b = (a_x + b_x, a_y + b_y, a_z + b_z)
    
  2. 减法

    a - b = (a_x - b_x, a_y - b_y, a_z - b_z)
    
  3. 标量乘法

    k * v = (k * v_x, k * v_y, k * v_z)
    
  4. 模(长度)

    ||v|| = sqrt(v_x^2 + v_y^2 + v_z^2)
    
  5. 归一化

    Normalized(v) = v / ||v||
    

点乘(Dot Product)

点乘 计算两个向量的内积,结果是一个标量。公式为:

a · b = a_x * b_x + a_y * b_y + a_z * b_z

应用

  1. 光照计算

    Intensity = max(0, N · L)
    

    其中 N 是法线向量,L 是光源方向向量。

  2. 夹角计算

    cos(θ) = (a · b) / (||a|| * ||b||)
    
  3. 投影

    Projection of a onto b = (a · b) / ||b||


叉乘(Cross Product)

叉乘 计算两个向量的外积,结果是一个垂直于原来的两个向量的向量。公式为:

a × b = (a_y * b_z - a_z * b_y, a_z * b_x - a_x * b_z, a_x * b_y - a_y * b_x)

应用

  1. 法线计算

    N = A × B
    
  2. 旋转: 叉乘用于计算物体旋转时的旋转轴和角度。

  3. 计算平行四边形面积

    Area = ||a × b||
    

在 Unity 中的应用

  1. 光照计算: 使用点乘计算光照强度,特别是在实现漫反射和镜面反射时。

  2. 法线计算: 使用叉乘计算物体表面的法线向量,用于光照和碰撞检测。

  3. 物体移动和旋转: 使用向量操作计算物体的移动、旋转和缩放。

  4. 碰撞检测: 使用向量来计算物体间的距离和相对位置,判断是否发生碰撞。


图形学中的应用

  1. 光照模型: 点乘用于计算漫反射光照强度,叉乘用于计算法线向量。

  2. 计算视角: 通过点乘计算视角的大小,用于相机视角和景深效果。

  3. 变换矩阵: 向量运算用于计算变换矩阵,进行模型、视图和投影的变换。

  4. 物体表面属性: 使用法线向量和光源方向向量进行阴影计算和表面细节渲染。

  5. 基于Unity:源码解析,unity进行了封装,大概是这意思
     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    namespace Ethan
    {
        public struct Vector3
        {
            public float x, y, z;
    
            public Vector3(float x, float y, float z)
            {
                this.x = x;
                this.y = y;
                this.z = z;
            }
    
            /// <summary>
            /// 两个向量之和 
            /// 应用:向前位移、力的合成、可取
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static Vector3 operator +(Vector3 a, Vector3 b)
            {
                return new Vector3(a.x + b.y, a.y + b.y, a.z + b.z);
            }
    
            /// <summary>
            /// 两个向量之差
            /// 应用:向后位移、计算反作用力
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static Vector3 operator -(Vector3 a, Vector3 b)
            {
                return new Vector3(a.x - b.y, a.y - b.y, a.z - b.z);
            }
    
            /// <summary>
            /// 计算向量和标量的乘法
            /// 应用:放大或缩小物体的模型、位移计算、计算力、加速度等物理量时,经常需要将向量与标量相乘
            /// </summary>
            /// <param name="k"></param>
            /// <param name="v"></param>
            /// <returns></returns>
            public static Vector3 operator *(Vector3 v, float k)
            {
                return new Vector3(k * v.x, k * v.y, k * v.z);
            }
    
            /// <summary>
            /// 计算两点之间的距离 
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static float Disance(Vector3 a, Vector3 b)
            {
                return Mathf.Sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z));
            }
    
            /// <summary>
            /// 计算向量-标准化(求模)
            /// 应用:主要用来计算向量的长度或大小
            /// </summary>
            public float Magnitude
            {
                get { return Mathf.Sqrt(x * x + y * y + z * z); }
            }
            /// <summary>
            /// 向量 归一化
            /// 将向量转换为单位向量(长度为 1 的向量),保留方向但调整大小
            /// 应用:单位向量在方向计算、光照计算、法线计算
            /// </summary>
            public Vector3 Normalized
            {
                get
                {
                    float mag = this.Magnitude;
                    if (mag > 0)
                    {
                        return this * (1 / mag);
                    }
                    return new Vector3(0, 0, 0); // 返回一个零向量,如果原向量的长度为零
                }
            }
            /// <summary>
            /// 点乘
            /// 应用:光照计算、背面裁剪、计算投影
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static float Dot(Vector3 a, Vector3 b)
            {
                return a.x * b.x + a.y * b.y + a.z * b.z;
            }
            /// <summary>
            /// 叉乘
            /// 应用:
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            public static Vector3 Cross(Vector3 a, Vector3 b)
            {
                return new Vector3(
                    a.y * b.z - a.z * b.y,
                    a.z * b.x - a.x * b.z,
                    a.x * b.y - a.y * b.x
                );
            }
    
        }
    }
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芊泽散人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值