在前几节中,我们从各种角度学习了线性代数,比如线性方程组,向量方程,矩阵方程,线性组合等,尽管底层都是同一个东西,但是站在不同的视角使用不同的描述就可以起到完全不同的效果,这一点对于我们程序员来说应该并不难理解,毕竟我们平时在编程时,底层的内存都是一样的,只不过表层的类型和语法不同,然后就起到了完全不同的效果,和线性代数是一样的思路,在本节我们将从一个深入矩阵内部细节的重要新视角理解线性代数。
线性代数部分
1.向量的线性无关
在之前我们学习了向量的线性组合,以二维平面为例,如果存在两条不平行的向量v1,v2\boldsymbol{v_1},\boldsymbol{v_2}v1,v2,那么它们所有的线性组合能够表示出整个二维空间中的所有向量,即span{v1,v2}span\{\boldsymbol{v_1}, \boldsymbol{v_2}\}span{v1,v2},那么考虑一个问题:这两个不平行的向量之间可以互相表示吗?也就是说是否能够使用v1\boldsymbol{v_1}v1的线性组合表示出v2\boldsymbol{v_2}v2,又或者是使用v2\boldsymbol{v_2}v2的线性组合表示出v1\boldsymbol{v_1}v1,显而易见,这是不行的,那么自然会提出疑问:在什么情况下,一组向量中的某一个向量能够使用其它向量的线性组合表示出来?
先将视角拉回上一节的齐次线性方程组,回顾一下,如果矩阵方程Ax=b\boldsymbol{A}\boldsymbol{x} = \boldsymbol{b}Ax=b中的b\boldsymbol{b}b是与矩阵A\boldsymbol{A}A行数相同的零向量,即Ax=0\boldsymbol{A}\boldsymbol{x} = \boldsymbol{0}Ax=0,那么此时就称Ax\boldsymbol{A}\boldsymbol{x}Ax构成的线性方程组是齐次的,在上一节中我们重点从解的视角讨论了齐次线性方程组,即平凡解与非平凡解,平凡解就是x=0\boldsymbol{x}=\boldsymbol{0}x=0时的解,容易得出一个齐次线性方程组必有平凡解,而非平凡解就是x!=0\boldsymbol{x}!=\boldsymbol{0}x!=0时的解,当齐次线性方程组的解中存在自由变量时,该齐次线性方程组存在无数个非平凡解。现在让我们从矩阵A\boldsymbol{A}A的视角来看待齐次线性方程组以及解的情况,考虑下方的矩阵方程:
a11a12a13a21a22a23a31a32a33x1x2x3=000 \left \\begin{array}{c} a_{11}\&a_{12}\&a_{13}\\\\ a_{21}\&a_{22}\&a_{23}\\\\ a_{31}\&a_{32}\&a_{33} \\end{array} \\right \left \\begin{array}{c} x_1\\\\ x_2\\\\ x_3 \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right a11a21a31a12a22a32a13a23a33 x1x2x3 = 000
我们将矩阵方程"拆开"变为向量方程,得出:
x1a11a21a31+x2a12a22a32+x3a13a23a33=000 x_1 \left \\begin{array}{c} a_{11}\\\\ a_{21}\\\\ a_{31} \\end{array} \\right + x_2 \left \\begin{array}{c} a_{12}\\\\ a_{22}\\\\ a_{32} \\end{array} \\right + x_3 \left \\begin{array}{c} a_{13}\\\\ a_{23}\\\\ a_{33} \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right x1 a11a21a31 +x2 a12a22a32 +x3 a13a23a33 = 000
显然此时就是以x1,x2,x3x_1, x_2, x_3x1,x2,x3为权将矩阵中对应的列向量进行线性组合,组合的目标是得出零向量,此时如果只存在平凡解,那么就是权x1,x2,x3x_1, x_2, x_3x1,x2,x3的值都为0,解的最终形式必定为:
x1x2x3=000 \left \\begin{array}{c} x_1\\\\ x_2\\\\ x_3 \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right x1x2x3 = 000
此时我们显然无法使用矩阵中某一些列向量的线性组合表示出某一个列向量,我们就称矩阵中的这批列向量是线性无关 的,标准的定义为:对于Rn\mathbb{R}^nRn中的一组向量{v1,v2,v3...vp}\{\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}\}{v1,v2,v3...vp},如果其对应的向量方程x1v1+x2v2+x3v3+...+xpvp=0x_1\boldsymbol{v_1}+x_2\boldsymbol{v_2}+x_3\boldsymbol{v_3}+...+x_p\boldsymbol{v_p} = \boldsymbol{0}x1v1+x2v2+x3v3+...+xpvp=0只存在平凡解,那么就称这组向量是线性无关的 。笔者的解读是:在一组同维度的一组向量中,如果其中任意一个 向量都不能由其余向量的线性组合表示出来,那么这组向量就是线性无关的,从几何角度的理解如下:

图1中只存在两条不平行的向量,由于任意单条向量的线性组合起到的效果就只有伸缩,因此其中一条向量绝对无法使用线性组合表示出另一条向量,那么图1中的{向量1,向量2}就是线性无关的,在图2中同样存在两条向量,但是它们是平行的,显然可以利用伸缩变化让其中一条向量表示出另一条向量,那么在图2中的{向量1,向量2}就不是线性无关的,然后是图3的情况,有三条互不平行的向量,由于二维平面中任意两条不平行向量都能够张成整个平面,即表示出平面中的任意向量,那么显然在三条不平行的向量中任取两条进行线性组合都能够表示出第三条向量,因此图3中的{向量1,向量2,向量3}不是线性无关的,最后是图4,此时向量2与向量3平行了,这意味着使用向量2和向量3的线性组合无法表示出向量1,但是线性无关的要求是:在同一维度的一组向量中,其中任意一条 向量都不能由其它向量的线性组合表示出来,但是显然图4中的向量2和向量3之间能够互相使用线性组合进行表示,因此图4中的{向量1,向量2,向量3}不是线性无关的。
容易推知,如果向量组中只存在一条向量,那么这组向量必然线性无关,如果向量组中向量的个数与向量所处的维度数相同,那么此时要分情况讨论,如果向量组中向量的个数大于向量所处的维度数,那么这组向量必然线性相关。而在矩阵中,矩阵的行数就是向量所处的维度数,矩阵的列数就是向量组中向量的个数,那么上方的关系从矩阵的视角看就是:当矩阵列数为1时,矩阵中的列向量必然线性无关,当矩阵的列数(向量个数)大于矩阵行数(向量所处维度)时,矩阵中的列向量必然线性相关。
2.向量的线性相关
同样的我们从齐次线性方程组的视角开始分析,对于齐次线性方程组的矩阵方程形式:
a11a12a13a21a22a23a31a32a33x1x2x3=000 \left \\begin{array}{c} a_{11}\&a_{12}\&a_{13}\\\\ a_{21}\&a_{22}\&a_{23}\\\\ a_{31}\&a_{32}\&a_{33} \\end{array} \\right \left \\begin{array}{c} x_1\\\\ x_2\\\\ x_3 \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right a11a21a31a12a22a32a13a23a33 x1x2x3 = 000
如果该齐次线性方程组存在非平凡解c1,c2,c3c_1, c_2, c_3c1,c2,c3,那么就可以写出向量的线性组合:
c1a11a21a31+c2a12a22a32+c3a13a23a33=000 c_1 \left \\begin{array}{c} a_{11}\\\\ a_{21}\\\\ a_{31} \\end{array} \\right + c_2 \left \\begin{array}{c} a_{12}\\\\ a_{22}\\\\ a_{32} \\end{array} \\right + c_3 \left \\begin{array}{c} a_{13}\\\\ a_{23}\\\\ a_{33} \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right c1 a11a21a31 +c2 a12a22a32 +c3 a13a23a33 = 000
此时显然可以利用向量运算的规律使用其它两个向量的线性组合表示出剩下的一个向量,比如:
a11a21a31=c2/c1a12a22a32+c3/c1a13a23a33 \left \\begin{array}{c} a_{11}\\\\ a_{21}\\\\ a_{31} \\end{array} \\right = c_2/c_1 \left \\begin{array}{c} a_{12}\\\\ a_{22}\\\\ a_{32} \\end{array} \\right + c_3/c_1 \left \\begin{array}{c} a_{13}\\\\ a_{23}\\\\ a_{33} \\end{array} \\right a11a21a31 =c2/c1 a12a22a32 +c3/c1 a13a23a33
对于其它列向量也是同理(分母为零的情况后面讨论,先给出标准定义),此时我们就称矩阵中的这一组列向量线性相关,也就是说:在同维度的一组向量中,如果存在 一条或多条向量能够使用其余向量的线性组合表示出来,那么就称这组向量是线性相关的。注意到在线性无关 中必须满足向量组中的任意 一条向量都不能由其它向量的线性组合表示出来,而在线性相关 中只要满足存在 一条向量能由其它向量的线性组合表示出来,这两个命题显然是互斥的,这意味着对于一组向量,要么满足线性相关,要么满足线性无关,不存在第三种情况。线性相关的标准代数定义为:对于Rn\mathbb{R}^nRn中的一组向量{v1,v2,v3...vp}\{\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}\}{v1,v2,v3...vp},如果存在不全为零的权c1,c2,c3...cpc_1, c_2, c_3...c_pc1,c2,c3...cp,使得线性组合c1v1,+c2v2+c3v3+...+cpvp=0c_1\boldsymbol{v_1},+c_2\boldsymbol{v_2}+c_3\boldsymbol{v_3}+...+c_p\boldsymbol{v_p} = \boldsymbol{0}c1v1,+c2v2+c3v3+...+cpvp=0,那么就成向量组{v1,v2,v3...vp}\{\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}\}{v1,v2,v3...vp}是线性相关的,并且称c1v1,+c2v2+c3v3+...+cpvp=0c_1\boldsymbol{v_1},+c_2\boldsymbol{v_2}+c_3\boldsymbol{v_3}+...+c_p\boldsymbol{v_p} = \boldsymbol{0}c1v1,+c2v2+c3v3+...+cpvp=0为该向量组的线性相关关系
其实存在二字在上方代数式中的体现就是分母是否为零,下面来详细的进行讨论,从我们擅长的几何视角出发,先来看下方几幅图:


在上图的两种情况中,容易得出两组向量都是线性相关的,但是红色的向量无法使用其它向量的线性组合进行表示,反过来说就是位于xyxyxy平面的向量在互相使用线性组合进行表示时,zzz轴上红色向量的权值必须为零。最后来总结一下:
| 在齐次线性方程组中 |
|---|
| 系数矩阵所有列都为主元列 <->解不存在自由变量<->只存在唯一解<->只存在平凡解<->系数矩阵的列向量组线性无关<->列向量组中的任意向量都不能由其余向量的线性组合表示出来 |
| 系数矩阵中存在非主元列<->解存在自由变量<->存在无数解<->同时存在平凡解和非平凡解<->系数矩阵的列向量组线性相关<->列向量组中存在向量能够由其余向量的线性组合表示出来 |
在上方我们只讨论了齐次线性方程组的情况,下面来看看非齐次线性方程组的情况,考虑非齐次线性方程组的矩阵方程:
a11a12a13a21a22a23a31a32a33x1x2x3=b1b2b3 \left \\begin{array}{c} a_{11}\&a_{12}\&a_{13}\\\\ a_{21}\&a_{22}\&a_{23}\\\\ a_{31}\&a_{32}\&a_{33} \\end{array} \\right \left \\begin{array}{c} x_1\\\\ x_2\\\\ x_3 \\end{array} \\right = \left \\begin{array}{c} b_1\\\\ b_2\\\\ b_3 \\end{array} \\right a11a21a31a12a22a32a13a23a33 x1x2x3 = b1b2b3
将其化为向量线性组合的形式:
c1a11a21a31+c2a12a22a32+c3a13a23a33=b1b2b3 c_1 \left \\begin{array}{c} a_{11}\\\\ a_{21}\\\\ a_{31} \\end{array} \\right + c_2 \left \\begin{array}{c} a_{12}\\\\ a_{22}\\\\ a_{32} \\end{array} \\right + c_3 \left \\begin{array}{c} a_{13}\\\\ a_{23}\\\\ a_{33} \\end{array} \\right = \left \\begin{array}{c} b_1\\\\ b_2\\\\ b_3 \\end{array} \\right c1 a11a21a31 +c2 a12a22a32 +c3 a13a23a33 = b1b2b3
显然我们可以将等号右侧的向量移动到等号左侧:
c1a11a21a31+c2a12a22a32+c3a13a23a33−b1b2b3=000 c_1 \left \\begin{array}{c} a_{11}\\\\ a_{21}\\\\ a_{31} \\end{array} \\right + c_2 \left \\begin{array}{c} a_{12}\\\\ a_{22}\\\\ a_{32} \\end{array} \\right + c_3 \left \\begin{array}{c} a_{13}\\\\ a_{23}\\\\ a_{33} \\end{array} \\right - \left \\begin{array}{c} b_1\\\\ b_2\\\\ b_3 \\end{array} \\right = \left \\begin{array}{c} 0\\\\ 0\\\\ 0 \\end{array} \\right c1 a11a21a31 +c2 a12a22a32 +c3 a13a23a33 − b1b2b3 = 000
然后就落入了齐次线性方程组的情况,只不过有一个向量的权值被固定了,我们完全可以按照处理齐次线性方程组的操作来进行处理,只需要固定一个向量就可以了。
笔者的奇思妙想
1.向量组中向量个数小于或等于向量所处维度时线性相关性的探讨
我们现在已经发现,当向量组中向量的个数等于一时,向量组必然线性无关,当向量组中向量的个数大于向量所处维度时,向量组必然线性相关,那么自然会提出疑问:当向量组中向量的个数小于或等于向量所处维度时,线性关系会是什么样子的?我们先讨论向量组中向量个数小于向量所处维度的情况,从二维开始讨论,此时如果向量个数小于维度数的话,那么向量组中要么没有向量,要么只存在一个向量,显然此时要么不构成线性关系,要么就是线性无关,然后是三维中的情况,此时向量组中向量个数的情况就是0,1或2,0时显然不构成线性关系,1时显然线性无关,关键是2,我们先利用向量平移后保持不变的特性,将两条向量的平移到起点为原点的位置,那么容易推知,这两条向量必然共面,并且当维度大于三维时,维度内任意两条向量同样是必然共面的,既然共面,那么就只存在平行或非平行两种情况了, 此时如果平行,那么线性相关,如果不平行,那么线性无关。然后是四维,向量组中向量的个数为0,1,2,3,容易发现0,1,2的情况和三维是一样的,我们只需要讨论3,显然我们可以从维度生成的角度来进行判断,如果这3个向量的线性组合能够生成3维空间,那么线性无关,如果生成的空间小于三维,那么线性相关,容易判断生成空间的维度不可能大于三,可以总结出通用结论了:当向量组中向量的个数小于向量所处维度时,如果向量生成的维度数等于向量的个数,那么该组向量线性无关,否则线性相关 。
下面来看看向量组中的向量个数等于向量所处维度的情况,此时显然可以套用上方向量个数小于向量所处维度的结论,那么总结处来的结论就是:当向量组中向量的个数小于等于向量所处维度时,如果向量生成的维度数等于向量的个数,那么该组向量线性无关,否则线性相关 ,最后再添加上大于的情况,得出覆盖所有情况的结论:当向量组中向量的个数小于等于向量所处维度时,如果向量生成的维度数等于向量的个数,那么该组向量线性无关,否则线性相关(生成维度不可能大于向量所处维度);当向量组中向量的个数大于向量所处的维度时,该向量组必然线性相关 。得出该结论最关键的核心就在于向量平移后保持不变的特性,这让我们能够将向量平移到原点进行讨论,大大的降低了讨论难度与情况数。
3.矩阵行列关系的第二次探讨
在理解了线性关系后,我们就可以从一个全新的视角理解矩阵的行与列了,即:矩阵的行数等于列向量所处的维度数,矩阵的列数等于列向量的个数 ,配合上线性相关的定义,矩阵的行与列之间就体现出了紧密的联系,也就是说我们可以把上方使用几何语言得出的结论翻译成矩阵语言,得出:当一个矩阵的列数(向量个数)小于等于行数时(向量所处维度),如果将矩阵中的各列进行线性组合后生成的维度等于矩阵的列数(向量个数),那么该矩阵的各列线性无关,否则线性相关,如果矩阵的列数大于行数,那么矩阵的各列必然线性相关。从直观上来看就是:
3.从非线性到线性
突然谈到这个其实是因为在下方探讨碰撞检测时出现了需要将非线性方程化为线性方程的需求,从几何的视角来看非常困难,因此在此处先从简单的代数视角开始一点点往后探讨,考虑下方的非线性方程组:
{x1x2+5x3=0x1+2x2+x3=03x1+x2+x3=0 \begin{cases} x_1x_2 + 5x_3 = 0\\ x_1 + 2x_2 +x_3 = 0\\ 3x_1+x_2 + x_3 = 0 \end{cases} ⎩ ⎨ ⎧x1x2+5x3=0x1+2x2+x3=03x1+x2+x3=0
关键就在于x1x2x_1x_2x1x2,对于非线性的方程组,线性代数中的方法就无法使用了,必须想办法处理掉该问题,笔者直接想到的策略就是先将x1x_1x1视为常量,表达出x2x_2x2,再将x2x_2x2视为常量,表达出x1x_1x1,也就是控制变量法,最终的目的是使用线性方程组的解法解出上方的非线性方程组并赋予有效几何意义,我们先将x1x_1x1视为常量,得出的线性方程组为:
{x1x2+5x3=02x2+x3=−x1x2+x3=−3x1 \begin{cases} x_1x_2 + 5x_3 = 0\\ 2x_2 +x_3 = -x_1\\ x_2 + x_3 = -3x_1 \end{cases} ⎩ ⎨ ⎧x1x2+5x3=02x2+x3=−x1x2+x3=−3x1
得出增广矩阵为:
x15021−x111−3x1 \left \\begin{array}{cc\|c} x_1\&5\&0\\\\ 2\&1\&-x_1\\\\ 1\&1\&-3x_1 \\end{array} \\right x1215110−x1−3x1
化为行化简矩阵,得出:
102x101−5x10025x1−2x12 \left \\begin{array}{cc\|c} 1\&0\&2x_1\\\\ 0\&1\&-5x_1\\\\ 0\&0\&25x_1-2x_1\^2 \\end{array} \\right 1000102x1−5x125x1−2x12
回代到线性方程组中:
{x2=2x1x3=−5x10=25x1−2x12 \begin{cases} x_2=2x_1\\ x_3 = -5x_1\\ 0 = 25x_1-2x_1^2 \end{cases} ⎩ ⎨ ⎧x2=2x1x3=−5x10=25x1−2x12
显而易见的一点是,如果25x1−2x12!=025x_1-2x_1^2 != 025x1−2x12!=0,那么线性方程组无解,我们先仅考虑有解的情况,此时得出两组有效解为:x1=0,x2=0,x3=0x_1 = 0,x_2 = 0, x_3 = 0x1=0,x2=0,x3=0和x1=12.5,x2=25,x3=−62.5x_1 = 12.5,x_2 = 25,x_3 = -62.5x1=12.5,x2=25,x3=−62.5,回代到最初的非线性方程组进行检验,得出的结果是正确的,然后再将x2x_2x2视为常量,得出线性方程组:
{x2x1+5x3=0x1+x3=−2x23x1+x3=−x2 \begin{cases} x_2x_1 + 5x_3 = 0\\ x_1 +x_3 = -2x_2\\ 3x_1 + x_3 = -x_2 \end{cases} ⎩ ⎨ ⎧x2x1+5x3=0x1+x3=−2x23x1+x3=−x2
得出增广矩阵为:
x25011−2x231−x2 \left \\begin{array}{cc\|c} x_2\&5\&0\\\\ 1\&1\&-2x_2\\\\ 3\&1\&-x_2 \\end{array} \\right x2135110−2x2−x2
化为行化简矩阵:
100.5x201−2.5x20012.5x2−0.5x22 \left \\begin{array}{cc\|c} 1\&0\&0.5x_2\\\\ 0\&1\&-2.5x_2\\\\ 0\&0\&12.5x_2-0.5x_2\^2 \\end{array} \\right 1000100.5x2−2.5x212.5x2−0.5x22
同理得出两组有效解:x1=0,x2=0,x3=0x_1=0,x_2=0,x_3=0x1=0,x2=0,x3=0和x1=12.5,x2=25,x3=−62.5x_1 = 12.5,x_2 = 25,x_3 = -62.5x1=12.5,x2=25,x3=−62.5,解是一样的,这里没点蹊跷是说不过去的,好好的来探讨一下吧,问题就是:为什么解是相同的,有什么具体的代数含义和几何含义?我们先讨几何含义:从直观上来看,如果将x1x_1x1和x2x_2x2都视为变量的话,那么x2x1+5x3=0x_2x_1 + 5x_3 = 0x2x1+5x3=0所表示出来的应该是一个三维曲面,而x1+2x2+x3=0x_1 + 2x_2 +x_3 = 0x1+2x2+x3=0和3x1+x2+x3=03x_1+x_2 + x_3 = 03x1+x2+x3=0表示的就是两张三维平面,最终非线性方程组的解就是三维曲面与两个平面的共同的交点,从上方代数计算的情况来看,该曲面至少和两个平面交与两个点,即(0,0,0)(0, 0, 0)(0,0,0)和(12.5,25,−62.5)(12.5, 25, -62.5)(12.5,25,−62.5),问题就是这两个点是否就是所有的解,我们先考虑两平面相交得出的解,去除非线性方程,得出线性方程组:
{x1+2x2+x3=03x1+x2+x3=0 \begin{cases} x_1 + 2x_2 +x_3 = 0\\ 3x_1+x_2 + x_3 = 0 \end{cases} {x1+2x2+x3=03x1+x2+x3=0
显然这是应该齐次线性方程组,并且由于向量的个数大于向量所处的维度,因此必然存在无数解,且解必然过原点,解的向量形式为:
x1x2x3=x3−15−251 \left \\begin{array}{c} x_1\\\\ x_2\\\\ x_3 \\end{array} \\right = x_3 \left \\begin{array}{c} -\\frac{1}{5}\\\\ -\\frac{2}{5}\\\\ 1 \\end{array} \\right x1x2x3 =x3 −51−521
绘制出具体图像为:
然后问题就变为了直线与曲面的交点,从几何上来看,一条直线与曲面的交点可能是0,1,2,3...不像线性关系那样要么唯一,要么无数,曲面不好绘制也不好想象,因此让我们切换到代数视角,使用回代法将所有未知数统一带入非线性方程中,得出方程:5x22−25x2=05x_2^2-25x_2=05x22−25x2=0,显然只存在两个交点,我们无论是将x1x_1x1视为常量还是将x2x_2x2视为常量都能够得出完整的解,现在的问题是:该方法是否具备通用性?如果方程的次数变得更高或更低又要如何处理?不过现在先让我们看到该方法的一个实际应用,即碰撞检测。
4.碰撞检测
碰撞检测是线性代数中一个实用性非常强操作,几何任何类型的游戏在底层的游戏引擎都在循环的进行碰撞检测,在AI中,也会大量的使用碰撞检测来进行信息的筛选,在此处我们基于线性代数的知识初步的探讨并设计基本的碰撞检测算法,以二维为例,从静态与动态两个视角进行探讨,先讨论最简单的点的碰撞,首先是静态视角,此时显然两点重合就相当于碰撞了,数值体现就是两个点的坐标相同了,然后是动态视角,我们假设最随机的情况,也就是点一直在随机移动,从直观上来看只需要循环检测两个点的坐标是否相同就可以了,但是有可能会出现在判断前点正好碰撞了,在判断时点又由于移动导致坐标不同了,那么就漏判了,而且不断的循环判断也会导致较大的开销,很明显点太小了,使用程序进行判断时很容易漏判,那么自然会想到让点变的"大一点",我们可以每隔一段时间就检测一次两点间的距离,如果距离低于我们预先设定的最小值,那么就开启循环的坐标碰撞判断,具体的判断设计还得考虑到点的移动速度,在后续小节的编程部分在具体设计吧。下面来看看线段的碰撞检测,首先依旧先考虑静态的情况,考虑下方的情况:
显然左侧的两条线段没有碰撞,右侧的两条线段碰撞了,考虑到后面还得使用向量进行动态的判断,因此我们最好使用接口一致的伪向量来进行静态碰撞检测判断,首先对左侧图进行判断,红色线段的伪向量为:1+t11+2t1\bigl\\begin{smallmatrix} 1+t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr1+t11+2t1,蓝色线段的伪向量表示为:1+2t24−t2\bigl\\begin{smallmatrix} 1+2t_2 \\\\ 4-t_2 \\end{smallmatrix}\\bigr1+2t24−t2,其中0<=t1<=1,0<=t2<=10 <= t_1 <= 1,0<=t_2 <=10<=t1<=1,0<=t2<=1,要注意的是t1t_1t1和t2t_2t2不表示相同的值,线段的伪向量实际上是表示出了线段上是所有点,显然如果两条线段碰撞了话,那么在线段上就会有重合点,因此自然的会想到 判断1+t11+2t1\bigl\\begin{smallmatrix} 1+t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr1+t11+2t1是否会存在等于1+2t24−t2\bigl\\begin{smallmatrix} 1+2t_2 \\\\ 4-t_2 \\end{smallmatrix}\\bigr1+2t24−t2的情况,即:1+t11+2t1=1+2t24−t2\bigl\\begin{smallmatrix} 1+t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 1+2t_2 \\\\ 4-t_2 \\end{smallmatrix}\\bigr1+t11+2t1=1+2t24−t2,将其转换为矩阵方程:
1−221\]\[t1t2\]=\[03\] \\left\[ \\begin{array}{c} 1\&-2\\\\ 2\&1\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} 0\\\\ 3\\\\ \\end{array} \\right\] \[12−21\]\[t1t2\]=\[03
如果线性方程组有解并且解落入t1,t2t_1,t_2t1,t2范围的话,那么似乎就可以判断出是否碰撞,显然我们好像发现了伪向量的代数意义和运算意义,笔者原先是将伪向量当作单纯的存储几何元素的容器,即几何元素参数方程的向量表示,现在看来由笔者自创的伪向量概念还可以更加强大,其代数与运算的意义似乎就是碰撞检测,而且可以兼容向量,矩阵和线性方程组的运算操作,当然具体意义还不明确,我们先来尝试一下:
将上方矩阵方程对应的增广矩阵化为行化简的形式,得出:
106/5013/5\] \\left\[ \\begin{array}{cc\|c} 1\&0\&6/5\\\\ 0\&1\&3/5\\\\ \\end{array} \\right\] \[10016/53/5
显然虽然有解,但是解的结果超出了t1t_1t1的范围,因此在几何上对应的就是线段没有碰撞,是正确的,下面来看看右侧的线段,这两条线段显然是碰撞了的,红色线段的伪向量为:1+3t11+t1\bigl\\begin{smallmatrix} 1+3t_1 \\\\ 1+t_1 \\end{smallmatrix}\\bigr1+3t11+t1,蓝色线段的伪向量为:1+3t22−2t2\bigl\\begin{smallmatrix} 1+3t_2 \\\\ 2-2t_2 \\end{smallmatrix}\\bigr1+3t22−2t2,其中0<=t1<=1,0<=t2<=10 <= t_1 <= 1,0<=t_2 <=10<=t1<=1,0<=t2<=1,然后判断伪向量等式1+3t11+t1=1+3t22−2t2\bigl\\begin{smallmatrix} 1+3t_1 \\\\ 1+t_1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 1+3t_2 \\\\ 2-2t_2 \\end{smallmatrix}\\bigr1+3t11+t1=1+3t22−2t2是否成立,并落入t1,t2t_1,t_2t1,t2范围,将其化为矩阵方程:
3−312\]\[t1t2\]=\[01\] \\left\[ \\begin{array}{c} 3\&-3\\\\ 1\&2\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} 0\\\\ 1\\\\ \\end{array} \\right\] \[31−32\]\[t1t2\]=\[01
将对应的增广矩阵化为行化简矩阵后得出:
101/3011/3\] \\left\[ \\begin{array}{cc\|c} 1\&0\&1/3\\\\ 0\&1\&1/3\\\\ \\end{array} \\right\] \[10011/31/3
有唯一解,且落入了t1,t2t_1, t_2t1,t2的范围,这意味着线段碰撞了,结果是正确的,我们将结果带入伪向量,看看点坐标得出的点坐标是否是相同的,首先带入红色线段的伪向量,得出点:1+3t11+t1=24/3\bigl\\begin{smallmatrix} 1+3t_1 \\\\ 1+t_1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 2 \\\\ 4/3 \\end{smallmatrix}\\bigr1+3t11+t1=24/3,然后带入蓝色线段伪向量,得出点:1+3t22−2t2=24/3\bigl\\begin{smallmatrix} 1+3t_2 \\\\ 2-2t_2 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 2 \\\\ 4/3 \\end{smallmatrix}\\bigr1+3t22−2t2=24/3,结果正确,我们有理由推测出如果求出了无数解,那么就意味着几何元素的交点不唯一,并且在无数点中的有效交点是落入有效ttt范围内的所有点,伪向量的强大超出了笔者的预想,我们可以将二维平面上线段的碰撞分为如下四种情况,然后一一进行讨论:
前两种情况在上文已经讨论过了,我们推测在单点碰撞时伪向量等式有唯一解且解落入t1,t2t_1,t_2t1,t2的有效范围,在不碰撞且不平行时,我们推测伪向量等式有唯一解但是解超出了t1,t2t_1,t_2t1,t2的有效范围,这里使用推测二字是因为我们仅仅只判断了特例,没有进行具备普遍意义的推导(笔者其实试过了,但推不出来),目前我们对于伪向量的运算意义还不够明确,无法得出普遍意义的结论,因此先从特例出发来加深我们的理解,考虑如下两条线段:
显然蓝色线段的伪向量为:1+3t11\bigl\\begin{smallmatrix} 1+3t_1 \\\\ 1 \\end{smallmatrix}\\bigr1+3t11,红色线段的伪向量为:1+2t22\bigl\\begin{smallmatrix} 1+2t_2 \\\\ 2 \\end{smallmatrix}\\bigr1+2t22,其中0<=t1<=1,0<=t2<=10 <= t_1 <= 1,0<=t_2 <=10<=t1<=1,0<=t2<=1,列出伪向量等式:1+3t11=1+2t22\bigl\\begin{smallmatrix} 1+3t_1 \\\\ 1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 1+2t_2 \\\\ 2 \\end{smallmatrix}\\bigr1+3t11=1+2t22,然后从解的情况来判断几何碰撞情况,此时我们先推断,解的情况应该是无解,因为两线段平行且不重合,先得出矩阵方程:
3−200\]\[t1t2\]=\[01\] \\left\[ \\begin{array}{c} 3\&-2\\\\ 0\&0\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} 0\\\\ 1\\\\ \\end{array} \\right\] \[30−20\]\[t1t2\]=\[01
显然该矩阵方程无解,增广矩阵最右侧列是主元列,目前看来似乎确实可以从伪向量等式中解的情况配合t1,t2t_1,t_2t1,t2的范围来判断碰撞情况,最后来看看如下两条线段:
上图的情况是线段平行且重合,先求出蓝色线段的伪向量为:1+2t11+2t1\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr1+2t11+2t1,红色线段的伪向量为:−1+3t2−1+3t2\bigl\\begin{smallmatrix} -1+3t_2 \\\\ -1+3t_2 \\end{smallmatrix}\\bigr−1+3t2−1+3t2,其中0<=t1<=1,0<=t2<=10 <= t_1 <= 1,0<=t_2 <=10<=t1<=1,0<=t2<=1,列出伪向量等式:1+2t11+2t1=−1+3t2−1+3t2\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} -1+3t_2 \\\\ -1+3t_2 \\end{smallmatrix}\\bigr1+2t11+2t1=−1+3t2−1+3t2,我们推测,会存在无数解,并且在首t1,t2t_1,t_2t1,t2限制后解的范围应该就是重合部分的线段,先将伪向量等式转换为向量方程:
2t12t1\]−\[3t23t2\]=\[−2−2\] \\left\[ \\begin{array}{c} 2t_1\\\\ 2t_1\\\\ \\end{array} \\right\] - \\left\[ \\begin{array}{c} 3t_2\\\\ 3t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} -2\\\\ -2\\\\ \\end{array} \\right\] \[2t12t1\]−\[3t23t2\]=\[−2−2
然后再得出矩阵方程:
2−32−3\]\[t1t2\]=\[−2−2\] \\left\[ \\begin{array}{c} 2\&-3\\\\ 2\&-3\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} -2\\\\ -2\\\\ \\end{array} \\right\] \[22−3−3\]\[t1t2\]=\[−2−2
得出增广矩阵的行化简形式:
1−32−1000\] \\left\[ \\begin{array}{cc\|c} 1\&-\\frac{3}{2}\&-1\\\\ 0\&0\&0\\\\ \\end{array} \\right\] \[10−230−10
显然存在一个自由变量,解是一条直线,回代到线性方程组中并使用自由变量表示基变量:
{t1=32t2−1 \begin{cases} t_1 = \frac{3}{2}t_2-1 \end{cases} {t1=23t2−1
变为几何意义更强的向量形式:
t1t2\]=t2\[321\]+\[−10\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = t_2 \\left\[ \\begin{array}{c} \\frac{3}{2}\\\\ 1\\\\ \\end{array} \\right\] + \\left\[ \\begin{array}{c} -1\\\\ 0\\\\ \\end{array} \\right\] \[t1t2\]=t2\[231\]+\[−10
然后开始分析几何意义,显然得出的直线与原本伪向量表示的线段并不平行,画出来是这样的:
与我们的直觉相违背了,虽然确实得出了一条直线,但是显然无法利用t1,t2t_1,t_2t1,t2的限制来表示出线段重合的部分,有必要好好探讨一下了,看回到矩阵方程:
2−32−3\]\[t1t2\]=\[−2−2\] \\left\[ \\begin{array}{c} 2\&-3\\\\ 2\&-3\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} -2\\\\ -2\\\\ \\end{array} \\right\] \[22−3−3\]\[t1t2\]=\[−2−2
解的含义就是将直线上的任意点带入该矩阵方程,得出的列向量的线性组合都能够表示出(−2,−2)(-2, -2)(−2,−2),也可以说是使用该矩阵处理位于解直线上的任意几何元素(点,线段,整条直线)都可以映射到点(−2,−2)(-2, -2)(−2,−2),但是似乎并没有碰撞含义,唯一的交点就是(2,2)(2, 2)(2,2),我们推测这个点是比较特殊的,也就是推测在线段重合时得出来的解直线与原线段的交点会位于一个重合端点,考虑下方线段:
好吧,是错的,笔者总感觉哪里怪怪的,得好好思考一下伪向量的运算意义了,首先伪向量本质上是几何元素参数方程的向量表示形式,表示的是一个几何元素内部的所有点,那么两个伪向量相等部分就应该是两个几何元素内点重合的部分,而我们使用代数手段求出来的解集并不直接意味着重合部分,而是要将解集中的有效部分带入参数方程才能够得出真正的重合部分,又或者说是在几何元素参数方程中满足解集中数值关系的点就是重合点,在解唯一时,解出来的是一个点,那么带入该点到伪向量参数方程得出的自然就是重合点,因此就让我们产生了解就是几何元素重合部分的错觉(其实在解唯一时解显然也不等于重合点的坐标,而是回代到参数方程中才能够得出重合点,是笔者写昏了头),实际上解应该是多个几何元素中重合部分满足的数值关系 ,并不是重合部分本身,但是从解的情况确实能够推断出几何元素的重合情况,比如无解时就意味着没有任意数值关系能够让两个几何元素发生重合,那么几何元素就必然不会重合,存在唯一解时就是存在唯一的数值关系让几何元素发生重合,由于带入唯一值到参数方程中得出的必然是唯一点,因此此时重合部分必然是一个点,最后对于存在无数解的情况,就是有无数个数值关系使得几何元素满足重合,将无数个不同的值带入参数方程得出的自然是无数个点,因此就是多点重合了,当然还得考虑参数ttt的情况,不过总体上来看解的情况是能够让我们大概的判断出几何元素的重合情况的,而笔者使用伪向量表示参数方程实际上就是让我们能够利用线性代数的算法高效,便利,快速的求出重合部分需要满足的数值关系,因此从本质上来看,单个伪向量表示的是纯粹的几何数据,不存在严格意义上的运算关系,但是伪向量的形式为我们提供了便利的判断几何元素重合部分数值关系的算法。这就像是编程中单独的数值只是纯粹的数据,不具备运算意义,但是数值一多,就会出现相加,相减,排序等人为进行的运算定义,在运算中不同的运算方式会拥有不同的效率,比如归并排序的效率就是比冒泡排序的效率高,这就是算法的意义,对应到伪向量中就是单个伪向量就是纯粹的数值,但是伪向量一多,对应的几何元素就会出现平行,重合,相交等人为定义的关系,为了快速的判断出这些关系,就产生了不同的算法,而伪向量的形式就与高效的线性代数算法在接口上保持了一致,让我们能够完美的将线性代数中强大的算法迁移过来,并以此从代数的角度快速求出多个伪向量之间几何关系对应的数值关系体现,所以从编程的视角来看,伪向量最大的意义就是与线性代数保持了接口的一致性。如果说伪向量是数据,那么向量操作就像是基本操作符,比如整数对应的+,-,*,/操作符,向量操作就是伪向量对应的平移,缩放操作符,矩阵就像是将基本的向量操作符封装后产生的复杂操作符,能够对伪向量进行映射,旋转,降维等复杂的操作。最终得出的结论就是:使用代数方式求得的数值关系必须回代到几何中的参数方程才能够体现出具体的几何意义 。
由上方的理解,再次看到多点重合的情况,我们的最终目的是使用已知的几何元素参数方程表示出重合部分的几何元素参数方程,那么问题就转换为:已知蓝色线段的伪向量为:1+2t11+2t1\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1+2t_1 \\end{smallmatrix}\\bigr1+2t11+2t1,红色线段的伪向量为:−1+3t2−1+3t2\bigl\\begin{smallmatrix} -1+3t_2 \\\\ -1+3t_2 \\end{smallmatrix}\\bigr−1+3t2−1+3t2,其中0<=t1<=1,0<=t2<=10 <= t_1 <= 1,0<=t_2 <=10<=t1<=1,0<=t2<=1,并且满足数值关系:t1=32t2−1t_1 = \frac{3}{2}t_2-1t1=23t2−1的点就是重合部分的点,求重合部分的参数方程:由于0<=t1<=00<=t_1<=00<=t1<=0,因此有0<=32t2−1<=10 <= \frac{3}{2}t_2-1 <= 10<=23t2−1<=1,并且还有0<=t2<=10<=t_2<=10<=t2<=1,列出不等式组:
{0<=32t2−1<=10<=t2<=1 \begin{cases} 0 <= \frac{3}{2}t_2-1 <= 1\\ 0<=t_2<=1 \end{cases} {0<=23t2−1<=10<=t2<=1
求得t2t_2t2的有效范围是:23<=t2<=1\frac{2}{3} <= t_2 <= 132<=t2<=1,这就是重合部分有效范围的参数形式了,我们使用t_3来表示,以此与原线段的范围区分开来,即23<=t3<=1\frac{2}{3} <= t_3 <= 132<=t3<=1因此重合部分的伪向量为:−1+3t3−1+3t3\bigl\\begin{smallmatrix} -1+3t_3 \\\\ -1+3t_3 \\end{smallmatrix}\\bigr−1+3t3−1+3t3,其中23<=t3<=1\frac{2}{3} <= t_3 <= 132<=t3<=1,带入t3t_3t3的边界值,检测出重合部分线段的端点为:(1,1),(2,2)(1, 1),(2, 2)(1,1),(2,2),结果正确,好在笔者高中时的数学学的还不错,这部分的推导少了任何一环都无法导出正确的结果,下面让我们提升难度,看看二维平面中多边形的碰撞问题,先考虑简单的正方形的碰撞,如下图:
先求出伪向量,蓝色正方形底边伪向量为:1+2t11\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1 \\end{smallmatrix}\\bigr1+2t11,加上平移向量后得出蓝色正方形伪向量:{1+2t11+2h1}\{\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1+2h_1 \\end{smallmatrix}\\bigr\}{1+2t11+2h1},其中0<=t1<=1,0<=h1<=10<=t_1<=1,0<=h_1<=10<=t1<=1,0<=h1<=1,同理求出红色正方形的伪向量为:{2+2t21+2h2}\{\bigl\\begin{smallmatrix} 2+2t_2 \\\\ 1+2h_2 \\end{smallmatrix}\\bigr\}{2+2t21+2h2},其中0<=t2<=1,0<=h2<=10<=t_2<=1,0<=h_2<=10<=t2<=1,0<=h2<=1,花括号表示集合含义,将花括号去掉就意味着正方形中的任意一个点,那么列出伪向量等式:1+2t11+2h1=2+2t21+2h2\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1+2h_1 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 2+2t_2 \\\\ 1+2h_2 \\end{smallmatrix}\\bigr1+2t11+2h1=2+2t21+2h2,满足该等式数值关系的点就是两个正方形碰撞范围的重合点,求出矩阵方程:
t1−t2h1−h2\]=\[120\] \\left\[ \\begin{array}{c} t_1\&-t_2\\\\ h_1\&-h_2\\\\ \\end{array} \\right\] = \\left\[ \\begin{array}{c} \\frac{1}{2}\\\\ 0\\\\ \\end{array} \\right\] \[t1h1−t2−h2\]=\[210
显然此时存在四个未知数,无法直接拆分为矩阵方程,先化为线性方程组并使用0进行填充:
{t1−t2+0h1+0h2=120t1+0t2+h1−h2=0 \begin{cases} t_1-t_2+0h_1+0h_2 =\frac{1}{2}\\ 0t_1+0t_2+h_1-h_2=0 \end{cases} {t1−t2+0h1+0h2=210t1+0t2+h1−h2=0
再化为矩阵方程:
1−100001−1\]\[t1t2h1h2\]=\[120\] \\left\[ \\begin{array}{c} 1\&-1\&0\&0\\\\ 0\&0\&1\&-1\\\\ \\end{array} \\right\] \\left\[ \\begin{array}{c} t_1\\\\ t_2\\\\ h_1\\\\ h_2 \\end{array} \\right\] = \\left\[ \\begin{array}{c} \\frac{1}{2}\\\\ 0\\\\ \\end{array} \\right\] \[10−10010−1\] t1t2h1h2 =\[210
分析解的情况,容易发现存在两个自由变量,解空间是一个平面,使用自由变量表示出基本变量,得出:
{t1=12+t2h1=h2 \begin{cases} t_1 = \frac{1}{2}+t_2\\ h_1 = h_2 \end{cases} {t1=21+t2h1=h2
得出不等式组:
{0<=12+t2<=10<=t2<=10<=h2<=1 \begin{cases} 0<=\frac{1}{2}+t_2 <=1\\ 0<=t_2 <=1\\ 0<=h_2 <=1\\ \end{cases} ⎩ ⎨ ⎧0<=21+t2<=10<=t2<=10<=h2<=1
求得重合部分有效范围:
{0<=t2<=120<=h2<=1 \begin{cases} 0<=t_2 <=\frac{1}{2}\\ 0<=h_2 <=1\\ \end{cases} {0<=t2<=210<=h2<=1
然后回代到伪向量中,此时回代到可以使用t1,h1t_1,h_1t1,h1回代到蓝色正方形中,也可以使用t2,h2t_2, h_2t2,h2回代到红色正方形中,不过在上方我们求出的是t2,h2t_2, h_2t2,h2在重合部分的有效范围,因此回代到红色正方形的伪向量中,并使用t3,h3t_3,h_3t3,h3替换掉重合部分的t2,h2t_2, h_2t2,h2,(不替换也可以,但是替换后看起来比较清晰,效果是相同的),得出重合部分伪向量为:{2+2t31+2h3}\{\bigl\\begin{smallmatrix} 2+2t_3 \\\\ 1+2h_3 \\end{smallmatrix}\\bigr\}{2+2t31+2h3},其中0<=t3<=12,0<=h3<=10<=t_3<=\frac{1}{2},0<=h_3<=10<=t3<=21,0<=h3<=1,把t3t_3t3的两个极值带入,可以得出边界端点(2,1+2h3),(3,1+2h3)(2, 1+2h_3),(3, 1+2h_3)(2,1+2h3),(3,1+2h3),结果正确,笔者这套方法的强大之处在于其通用性,无论几何元素的维度,是复杂还是简单,都可以利用最终数值关系结果的范围在原几何元素中得出重合部分的参数方程,下面考虑一个复杂点的情况:
先求出蓝色直角三角形的伪向量,首先其底边伪向量为:1+2t11\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1 \\end{smallmatrix}\\bigr1+2t11,其中0<=t1<=10<=t_1<=10<=t1<=1,然后单独提取出直角三角形:
具体流程就是根据平移的距离缩放底边,然后再把缩放后的新线段平移回去,显然平移时要把缩放后线段的左端点平移到直角三角形内部线段的左端点,先求出缩放比例因子uuu,这次我们使用代数的方法来求,首先求出斜边伪向量为:3−2t21+3t2\bigl\\begin{smallmatrix} 3-2t_2 \\\\ 1+3t_2 \\end{smallmatrix}\\bigr3−2t21+3t2,0<=t2<=10<=t_2<=10<=t2<=1,假设底边向上平移了h,0<=h<=3h,0<=h<=3h,0<=h<=3,,那么新线段对应的yyy就是1+h1+h1+h,即:
要求出?点的x坐标,利用斜边伪向量带入y=1+hy = 1+hy=1+h求出x=3−2h3x = 3-\frac{2h}{3}x=3−32h,在减去左侧垂线段的xxx坐标,得出平移过程中线段的长度d=2−2h3d=2-\frac{2h}{3}d=2−32h,由于底边长为2,因此在平移过程有:2∗u=d2*u = d2∗u=d,得出缩放比例因子u=1−h3u = 1-\frac{h}{3}u=1−3h,由于向量数乘是以原点为缩放参考点的,因此缩放后会出现平移,我们得把线段平移到直角三角形内部,即:
缩放后的平移效果会将新线段左端点变为(u,u)(u, u)(u,u),平移后左端点会变为(u,u+h)(u, u+h)(u,u+h),此时得出的就是新线段初始位置点,目标点是位于直角三角形内部的(1,1+h)(1, 1+h)(1,1+h),得出缩放平移向量为(1−u,1−u)(1-u, 1-u)(1−u,1−u),因此得出直角三角形的伪向量为:0h+(1−h3)1+2t11+h3h3=1+2t1−2ht131+h\bigl\\begin{smallmatrix} 0 \\\\ h \\end{smallmatrix}\\bigr+(1-\frac{h}{3})\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1 \\end{smallmatrix}\\bigr+\bigl\\begin{smallmatrix} \\frac{h}{3}\\\\ \\frac{h}{3} \\end{smallmatrix}\\bigr =\bigl\\begin{smallmatrix} 1+2t_1-\\frac{2ht_1}{3} \\\\ 1+h \\end{smallmatrix}\\bigr0h+(1−3h)1+2t11+3h3h=1+2t1−32ht11+h,其中0<=t1<=1,0<=h<=30<=t_1<=1,0<=h<=30<=t1<=1,0<=h<=3验证一下,带入h = 0得出的线段参数方程为1+2t11\bigl\\begin{smallmatrix} 1+2t_1 \\\\ 1 \\end{smallmatrix}\\bigr1+2t11,正确,带入h = 3得出点(1,4)(1, 4)(1,4),正确,然后求出长方形的参数方程:1+4t21+h2\bigl\\begin{smallmatrix} 1+4t_2 \\\\ 1+h_2 \\end{smallmatrix}\\bigr1+4t21+h2,其中0<=t2<=1,0<=h2<=10<=t_2<=1,0<=h_2<=10<=t2<=1,0<=h2<=1,然后列出伪向量等式:1+2t1−2ht131+h=1+4t21+h2\bigl\\begin{smallmatrix} 1+2t_1-\\frac{2ht_1}{3} \\\\ 1+h \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 1+4t_2 \\\\ 1+h_2 \\end{smallmatrix}\\bigr1+2t1−32ht11+h=1+4t21+h2,注意到在式子中出现了ht1ht_1ht1,这意味着该式不满足线性关系,我们得先想办法让其满足线性关系,否则就无法使用线性代数的算法了,显然无法直接将ht1ht_1ht1视为一个整体,因为在式子中出现了单个的t1t_1t1,此时就可以利用我们在上方推导出来的控制变量法了,我们先假定hhh为常量,t1t_1t1为变量,得出线性方程组:
{(2−2h3)t1−4t2+0h2=00t1+0t2−h2=−h \begin{cases} (2-\frac{2h}{3})t_1-4t_2+0h_2 = 0\\ 0t_1 + 0t_2 - h_2 = -h \end{cases} {(2−32h)t1−4t2+0h2=00t1+0t2−h2=−h
行化简矩阵为:
16h−300001−h\] \\left\[ \\begin{array}{ccc\|c} 1\&\\frac{6}{h-3}\&0\&0\\\\ 0\&0\&1\&-h \\end{array} \\right\] \[10h−360010−h
使用自由变量表示基变量,得出线性方程组形式的解为:
{t1=6t23−hh2=h \begin{cases} t_1 = \frac{6t_2}{3-h}\\ h_2 = h \end{cases} {t1=3−h6t2h2=h
列出不等式组:
{0<=6t23−h<=10<=t2<=10<=h=h2<=1 \begin{cases} 0 <= \frac{6t_2}{3-h} <= 1\\ 0 <= t_2 <= 1\\ 0 <= h=h_2 <= 1 \end{cases} ⎩ ⎨ ⎧0<=3−h6t2<=10<=t2<=10<=h=h2<=1
解出:
{0<=t2<=3−h60<=h=h2<=113<=3−h6<=12 \begin{cases} 0 <= t_2 <= \frac{3-h}{6}\\ 0 <= h=h_2 <= 1\\ \frac{1}{3} <= \frac{3-h}{6} <= \frac{1}{2} \end{cases} ⎩ ⎨ ⎧0<=t2<=63−h0<=h=h2<=131<=63−h<=21
解中最核心的地方就在于t2<=3−h6 t_2 <= \frac{3-h}{6}t2<=63−h,这意味着当hhh在000到111变化的时候,t2t_2t2会拥有不同的取值范围,先回代到长方形的参数方程中,使用t3t_3t3替代t2t_2t2,h3h_3h3替代h2h_2h2:1+4t31+h3\bigl\\begin{smallmatrix} 1+4t_3 \\\\ 1+h_3 \\end{smallmatrix}\\bigr1+4t31+h3,其中0<=t3<=3−h6,0<=h3<=1,h=h30 <= t_3 <= \frac{3-h}{6},0 <= h_3 <= 1,h = h_30<=t3<=63−h,0<=h3<=1,h=h3,来分析一下几何含义,首先由于1<=1+h3<=21<=1+h_3<=21<=1+h3<=2,因此碰撞部分的yyy坐标范围是1,21, 21,2,是正确的,关键在于xxx坐标,先得出1<=1+4t3<=3−2h31 <= 1+4t_3 <= 3-\frac{2h}{3}1<=1+4t3<=3−32h,因此碰撞部分的xxx坐标范围是1,3−2h31, 3-\\frac{2h}{3}1,3−32h,左边可以确定是正确的,关键是右边,由于hhh本身的含义是底边向上平移的距离,而3−2h33-\frac{2h}{3}3−32h显然满足线性关系,我们带入h=0h=0h=0,得出xxx坐标范围为1,31, 31,3,这意味着当底边没有向上平移时,碰撞部分xxx坐标的范围是1,31, 31,3,是正确的,带入h=1h = 1h=1,得出xxx坐标的范围是1,731, \\frac{7}{3}1,37,这意味着当底边向上平移111个单位是,xxx坐标的范围变为1,731, \\frac{7}{3}1,37,如果能够验证这是正确的,那么由3−2h33-\frac{2h}{3}3−32h的线性关系就可以确定我们解出来的就是碰撞部分的参数方程,只需要验证碰撞部分右上方端点的xxx坐标就可以了,容易计算出结果就是73\frac{7}{3}37是正确的,成功的求出了碰撞区域的参数方程。容易发现关键在于从非线性到线性的转换,我们在求解时将一个变量视为固定常量,在解出结果后又把该常量视为变量来进行动态分析,思想很简单,但是其中肯定藏着什么奥妙,不过先不具体分析,让我们从数学家变为程序员,继续项目的设计吧。
加上完整的编程部分后超出了文章的字数限制,因此笔者分篇到了另一篇blog中,请移步至:《AI底层系列:用C++实现线性代数的公式推导与算法设计-7.线性相关与线性无关(编程部分)》












