Unity3D -- 图形 -- 向量运算

向量运算是3D图形,物理,动画的基础。


向量加法(Addition)

两个向量相加时,结果等于把这两个向量作为台阶,注意,两个向量的顺序不重要,结果是一样的。

如果第一个向量是空间中的点,则可以把第二个向量理解成一个“偏移量”。比如,要想找到一个平面上的5个单位的高度的点,可以用下面的计算式子:

  1. var pointInAir = pointOnGround + new Vector3(0, 5, 0);  
var pointInAir = pointOnGround + new Vector3(0, 5, 0);

如果向量表示的是力,那这就可以更直观地认为它是力的方向和大小(magnitude ,下同)。两个表示力的向量相加的结果是一个新的向量,这个向量等于两个力的结合。这个概念在使用多力的组件时非常有用。


向量减法(Subtraction)

向量减法常用于取得一个对象到另一个对象之间的方向和距离。注意减法式子中的参数顺序会影响到结果:

  1. // 向量d与c的力的大小值相同,但方向不同。  
// 向量d与c的力的大小值相同,但方向不同。
  1. var c = b - a;  
  2. var d = a - b;  
var c = b - a;
var d = a - b;

和数字一样,加一个负向量等于减去一个正向量。

  1. var c = a - b;  
  2. var c = a + -b;  
var c = a - b;
var c = a + -b;

负向量与正向量的的力的大小相同,但方向刚好相反。


标量的乘法和除法(Scalar Multiplication & Division)

讨论向量的时候,通常指的是普通的数字(比如一个浮点值)。意思是说标量只有比例或者说(力的)大小,而向量既有方向又有大小。

向量乘以一个标量的结果还是一个向量,结果向量的方向与原向量相同。但是,新向量的大小等于原向量的大小乘以标量的值。

同样地,标量除法也是一样的。

这些运算在向量表示位移或力的时候非常有用。可以改变向量的大小,而不改变其方向。

当任何向量除以自己的大小时,结果是大小为1的向量,也叫做单位向量(Normalized Vector)。如果单位向量乘以一个标量,那么结果的大小等于那个标量的值。这在力的方向是常量,但是力度是可变时很有用(比如车轮的力一直让车前行,但是功率是由驾驶员控制的)。


标量积(点积),Scalar Product(Dot Product)

点积是用两个向量返回一个标量,这个标量等于两个向量的大小相乘,结果再乘以两个向量的夹角的余弦值(cosine)。当两个向量都是单位向量时,余弦值的本质是第一个向量向第二个向量延伸的方向(反之则反之,参数的顺序不重要)

很容易想到一个计算式来计算此余弦值(cosine)。然而,可以直观地知道一些主要的余弦值:


点积是一个非常简单的运算,可以用于代替 Math.Cos 函数,以及代替向量大小运算(意义不同,但效果一样)。但是,计算点积占的CPU很少,所以是个有价值的优化点。


向量积(叉积),Vector Product(Cross Product)

另一个运算是为2D和3D向量定义的,其实多少维的向量都可以:叉积。相比而言,只对3D向量有意义。输入两个向量,输出一个向量。

结果向量与两个输入向量正交(垂直)。“左手法则”可以用于从输入向量得到结果向量的方向。如果第一个向量与拇指(Thumb)的方向相同,第二个向量与食指(forefinger)的方向相同,那么结果与中指(Middle finger)的方向相同。如果两个入参向量的方向相反,则结果也相同,但大小相同。

结果向量的大小等于两个输入向量的相乘,结果再乘以两个向量的夹角的正弦值(sine)。下面是一些常用的值:

叉积看起来有点复杂,因为它组合了几个不同的返回值。但是,就像是点积一样很有用。可以用于优化代码。


计算法向量(垂直向量)

法向量(向量垂直于平面)在生成mesh和路径跟踪时用得很多。给出平面上的3个点,也就是三角网格(mesh triangle)的角上的点,很容易找到法线:用3个点中的任一个点,然后分别用另两个点与之相减,得到两个向量:

  1. var a: Vector3;  
  2. var b: Vector3;  
  3. var c: Vector3;  
  4.   
  5. var side1: Vector3 = b - a;  
  6. var side2: Vector3 = c - a;  
var a: Vector3;
var b: Vector3;
var c: Vector3;

var side1: Vector3 = b - a;
var side2: Vector3 = c - a;
这两个向量的叉积得到第3个向量,此向量与平面垂直。“左手法则”可以用于决定点积函数的入参的顺序。从顶向下看平面,第一个向量应该顺时针绕着第二个向量。
  1. var perp: Vector3 = Vector3.Cross(side1, side2);  
var perp: Vector3 = Vector3.Cross(side1, side2);

入参顺序反之则结果的方向也相反。

对于mesh,法向量也必须归一化,可以用Normalized属性实现,但麻烦的是它有时不管用。也可以通过除以向量的大小得到归一化的法向量。

  1. var perpLength = perp.magnitude;  
  2. perp /= perpLength;  
var perpLength = perp.magnitude;
perp /= perpLength;

结果是三角形的面积等于perpLength/2。如果想得到整个mesh的平面面积或者想基于其相对面积随机选择三角形时很有用。

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值