笛卡儿坐标系
二维笛卡儿坐标系
一个二维笛卡儿坐标系包含了两个部分的信息:
(1)一个特殊的位置,即原点,它是整个坐标系的中心;
(2)两条过原点的互相垂直的矢量,即x轴和y轴。这些坐标轴也被称为是该坐标系的基矢量。
三维笛卡儿坐标系
在三维笛卡儿坐标系中,我们需要定义3个坐标轴和一个原点。
这三个坐标轴也被称为是该坐标系的基矢量。通常情况下,这三个坐标轴之间是互相垂直的,且长度为1,这样的基矢量被称为标准正交基,但这并不是必须的。例如,在一些坐标系中坐标轴之间互相垂直但长度不为1,这样的矢量被称为正交基。正交可以理解为相互垂直。
左手坐标系和右手坐标系
如果两个坐标系具有相同的旋向性,那么就可以通过旋转的方法来让它们的坐标轴指向重合。但是如果不具有旋向性,就无法达到重合的目的。
左手右手坐标系都是大拇指指向+x轴,食指指向+y轴,中指指向+z轴方向。
左手法则:举起左手,握拳,伸出大拇指让它指向旋转轴正方向,那么旋转的正方向就是剩下4个手指的弯曲方向。右手坐标系同理。在左手坐标系中,旋转正方向是顺时针的,而在右手坐标系中,旋转正方向是逆时针的。
Unity使用的坐标系
对于模型空间和世界空间,Unity使用的是左手坐标系;
对于观察空间来说,Unity使用的是右手坐标系。观察空间,就是以摄像机为原点的坐标系。在这个坐标系中,摄像机的前向是z轴的负方向,z轴越小,物体的深度越大,离摄像机越远。
练习题
(1)在非常流行的建模软件3ds Max中,默认的坐标轴方向是:x轴正方向指向右方,y轴 正方向指向前方,z轴正方向指向上方。那么它是左手坐标系还是右手坐标系?
答:右手!!!
(2)在左手坐标系中,有一点的坐标是(0,0,1),如果把该点绕y轴正方向旋转+90度,旋转后的坐标是什么?如果是在右手坐标系中,同样有一点坐标为(0,0,1),把它绕y轴正方向旋转+90度,旋转后坐标是什么?
答:(1,0,0)、(1,0,0)
(3)在Unity中,新建的场景中主摄像机的位置位于世界空间中的(0,1,-10)位置。在不改变摄像机的任何设置的情况下,在世界空间中的(0,1,0)位置新建一个球体,在摄像机的观察空间下,该球体的z值是多少?在摄像机的模型空间下,该球体的z值又是多少?
答:-10,、10
点和矢量
点是n维空间中的一个位置,它没有大小、宽度这类概念。在笛卡儿坐标系中,我们可以使用2个或3个实数来表示一个点的坐标,如:P = (Px, Py) 表示二维空间的点,P = (Px, Py, Pz) 表示三维空间中的点。
矢量(向量)复杂一些。矢量存在的意义更多是为了和标量区分开来。通常来讲,矢量是指n维空间中一种包含了模和方向的有向线段,速度就是一种矢量。而标量只有模没有方向,距离就是一种标量。
具体来讲:
(1)矢量的模指的是这个矢量的长度。一个矢量的长度可以是任意的非负数。
(2)矢量的方向则描述了这个矢量在空间中的指向。
矢量的表示方法和点类似。我们可以用v=(x,y)来表示二维矢量,用v=(x,y,z)来表示三维矢量,用v=(x,y,z,w)来表示四维矢量
(3)对于标量,我们用小写字母表示,如a,b,x,y、z等
(4)对于矢量,我们用小写的粗体字母表示,如a,b,u,v等
(5)对于后面要学的矩阵,我们用大写粗体字母表示,如A,B,S,M,R等
一个矢量通常由一个箭头表示。矢量的头指的是它的箭头所在的端点处,尾指的是另一个端点处。
通常,矢量被用于表示相对于某个点的偏移,也就是说它是一个相对量。只要矢量的模和方向保持不变,无论放在哪里,都是同一个矢量。
点和矢量的区别
矢量通常用于描述偏移量,可以描述相对位置,即相对另一个点的位置。此时矢量的尾是一个位置,那么矢量的头就可以表示另一个位置了。一个点可以用于指定空间中的一个位置(相对于原点的位置)。如过把矢量的尾部固定值坐标系原点,那么这个矢量的表示就和点的表示重合了。我们可以认为,任何一个点都可以表示成一个从原点出发的矢量。我们将用于表示方向的矢量称为方向矢量。
矢量运算
矢量和标量乘法/除法
只需要把每个分量和标量相乘即可。
kv=(kv_{x},kv_{y},kv_{z})
一个矢量也可以被一个非零的标量除。这等于和这个标量的倒数相乘
\frac{v}{k}=\frac{(x,y,z)}{k}=\frac{1}{k}(x,y,z)=\left(\frac{x}{k},\frac{y}{k},\frac{z}{k}\right)
对于乘法来说,矢量和标量位置可以互换。对于除法,只能是矢量被标量除。从几何意义上看,把一个矢量v和一个标量k相乘,意味着对矢量v进行一个大小为|k|的缩放。
结果也是一个矢量。
矢量的加法和减法
我们可以对两个矢量进行相加或相减,结果是一个相同维度的新矢量。
我们只需要把两个矢量的对应分量进行相加减即可。
a+b=(a_{x}+b_{x},a_{y}+b_{y},a_{z}+b_{z})
a-b=(a_{x}-b_{x},a_{y}-b_{y},a_{z}-b_{z})
一个矢量不可以和一个标量相加或相减,不可以和不同维度的矢量进行运算。
对于加法,我们可以把矢量a的头连接到矢量b的尾,然后画一条从a的尾到b的头的矢量,来得到a和b相加后的矢量。如果我们从一个起点开始进行了一个位置偏移a,然后又进行一个位置偏移b,那么就等于同时进行a+b的位置偏移,这被称为三角形定则。
在图形学中矢量通常用于描述位置偏移,因此我们可以用矢量的加法和减法来计算一点相对于另一点的位移。
假如空间内有两点a和b,我们可以用矢量a和b来表示它们相对于原点的位移。如果想计算a相对于b的位移,我们可以通过把b和a相减得到。
矢量的模
矢量的模是一个标量,可以理解为是矢量在空间中的长度。符号是在矢量两旁分别加上一条垂直线。
三维矢量计算公式如下
|v| = \sqrt{v_{x}^2+v_{y}^2+v_{z}^2}
二维矢量的模就是构成直角三角形的斜边长度。
单位矢量
很多时候,我们只关心矢量的方向而不是模,就需要单位矢量。
单位矢量指模为1的矢量。单位矢量也被称为被归一化的矢量。对任何给定的非零矢量,把它转换成单位矢量的过程就被称为归一化。给定任意非零矢量v,我们可以计算和v方向相同的单位矢量。我们通过在一个矢量的头上添加一个戴帽符号来表示单位矢量 \hat{v} 。为了对矢量进行归一化,我们可以用矢量除以该矢量的模得到。
归一化:\hat{v}=\frac{v}{|v|},v是任意非零矢量
零矢量(即矢量的每个分量值都为0)是不可以被归一化的。因为做除法运算时分母不能为0。
从几何意义上看,对二维空间来说,我们可以画一个单位圆。单位矢量就是从圆心出发、到圆边界的矢量。
在三维空间中,单位矢量就是从一个单位球的球心出发、到达球面的矢量。
矢量的点积
矢量乘法有两种:点积和叉积。
在Unity Shader 中,我们可以直接使用形如 dot(a, b) 的代码来对两个矢量值进行点积的运算。
点积公式有两种:
第一种点积公式
公式一:a\cdot b=(a_{x},a_{y},a_{z})\cdot (b_{x},b_{y},b_{z})=a_{x}b_{x}+a_{y}b_{y}+a_{z}b_{z}
矢量的点积满足交换律a\cdot b=b\cdot a
点积的其中一个几何意义就是投影。
假设有一个单位矢量\hat{a}和另一个长度不限的矢量b。现在,我们希望得到b平行于\hat{a}的一条直线上的投影。那么,我们就可以使用点积\hat{a}\cdot b来得到b在\hat{a}方向上的有符号的投影。我们可以认为,现在有一个光源,它发出的光是垂直于\hat{a}方向的,那么b在\hat{a}方向上的投影就是b在\hat{a}方向上的影子。
投影的值可能是负数。投影结果的正负号与\hat{a}和b的方向有关:当它们方向相反(夹角大于90度)时,结果小于0;当它们的方向互相垂直时,结果等于0;当它们的方向相同(夹角小于90度)时,结果大于0。
点积的符号可以让我们知道两个矢量的方向关系。
任何两个矢量的点积a\cdot b等同于b在a方向上的投影值,再乘以a的长度。
点积具有一些很重要的性质
(1)点积可结合标量乘法
点积的操作数之一可以是另一个运算的结果,即矢量和标量相乘的结果。
(ka)\cdot b=a\cdot (kb)=k(a\cdot b)
也就是说,对点积其中一个矢量进行缩放的结果,相当于对最后的点积结果进行缩放。
(2)点积可结合矢量加法和减法
结合指点积的操作数可以是矢量相加或相减后的结果
a\cdot (b+c)=a\cdot b+a\cdot c
把c换成-c可以得到减法版本。
(3)一个矢量和本身进行点积的结果,是该矢量的模的平方
v\cdot v=v_{x}v_{x}+v_{y}v_{y}+v_{z}v_{z}=|v|^2
这意味着,我们可以直接用点积来求矢量的模,而不需要使用模的计算公式。很多情况我们只是想要比较两个矢量的长度大小,因此可以直接使用点积的结果。
第二种点积公式
这种方法是从三角代数的角度出发的,这种表示方法更加具有几何意义,因为它可以明确地强调出两个矢量之间的角度。
公式二:a\cdot b=|a||b|cos\theta
假设,我们对两个单位矢量进行点积\hat{a}\cdot \hat{b},我们知道\hat{b}的模为1,且cos\theta=\frac{邻边}{斜边}。我们可以发现,\hat{a}\cdot \hat{b}的结果刚好就是cos\theta对应的直角边,因此我们可以得到
\hat{a}\cdot \hat{b}=\frac{邻边}{斜边}=cos\theta
这就是说,两个单位矢量的点积等于它们之间夹角的余弦值,再用性质一可得性质二
a\cdot b=(|a|\hat{a})\cdot (|b|\hat{b})=|a||b|(\hat{a}\cdot \hat{b})=|a||b|cos\theta
也就是说,两个矢量的点积可以表示为两个矢量的模相乘,再乘以它们之间的余弦值。
利用这个公式我们还可以求两个向量之间的夹角。
\theta=arcos(\hat{a}\cdot \hat{b}),假设\hat{a}和\hat{b}是单位向量。其中,arcos是反余弦操作。
矢量的叉积
矢量的叉积也被称为外积。矢量叉积的结果仍是一个矢量,而非标量。
叉积的名称来源于它的符号a\times b。同样,这个叉号也是不可省略的。两个矢量的叉积公式
a\times b=(a_{x},a_{y},a_{z})\times (b_{x},b_{y},b_{z})=(a_{y}b_{z}-a_{z}b_{y},a_{z}b_{x}-a_{x}b_{z},a_{x}b_{y}-a_{y}b_{x})
23-32, 31-13, 12-21 23-31-12
叉积不满足交换律,满足反交换律a\times b=-(b\times a)。叉积不满足结合律
叉积的几何意义,对两个矢量进行叉积的结果会得到一个同时垂直于这两个矢量的新矢量。
新矢量的模和方向是什么呢?a\times b的长度等于a和b的模的乘积再乘以它们之间夹角的正弦值。
|a \times b|=|a||b|sin\theta
这里使用的是正弦值。这和平行四边形的面积计算公式是一样的。