图形学知识基础:三维变换,旋转(欧拉角旋转与万向锁,绕任意轴旋转,四元数)
三维变换
与上一篇文章中的二维变换类似,我们可以使用一个 3*3 的矩阵来表示一个三维的线性变换:
并且矩阵 的 , 和 即为 变化后的值, , 和 即为 变化后的值, , 和 即为 变化后的值。
仿射变换的公式为:
同样的,我们可以通过引入齐次坐标来表示仿射变换,公式为:
例如缩放s倍的矩阵为:
旋转变换
相比其他变换,旋转变换相对的要复杂一些。首先我们要确定我们的坐标系是左手坐标系还是右手坐标系,这会影响到x,y,z三个轴的相对关系,本文我们使用右手坐标系来进行相关的运算。右手坐标系如下图,右手四指弯曲的方向代表x轴到y轴的方向,大拇指方向代表z轴方向。
我们先来看看在三维空间中绕x,y,z三个轴中的某个轴逆时针旋转 角度的矩阵是如何的
- 绕x轴旋转,则可以看作是在yz平面的二维旋转,x轴的(1,0,0)不变,y轴(0,1,0)变为(0,cos,sin),z轴的(0,0,1)变为(0,-sin,cos),因此对应的矩阵为:
- 绕y轴旋转,则可以看作是在xz平面的二维旋转,y轴的(0,1,0)不变,x轴(1,0,0)变为(cos,0,-sin),z轴的(0,0,1)变为(sin,0,cos),因此对应的矩阵为:
- 绕z轴旋转,则可以看作是在xy平面的二维旋转,z轴的(0,0,1)不变,x轴(1,0,0)变为(cos,sin,0),y轴的(0,1,0)变为(-sin,cos,0),因此对应的矩阵为:
的结合使用
两者结合使用
对于如下表达式我们应该如何理解
通过上一篇提到的复合变换,上面式子表达的应该是先绕x轴旋转,然后再绕y轴旋转。假设原先物体的x轴方向为(1,0,0),y轴方向为(0,1,0),z轴方向为(0,0,1),我们先将其绕x轴逆时针旋转 度,即 操作。此时物体自身的y轴(0,1,0)会跟着x轴的旋转变为(0,cos,sin),记作 。那么我们再做 操作时,旋转的y轴是原先的 y=(0,1,0) 还是 =(0,cos,sin) ?这是两种完全不一样的情况,如下图
垂直向上较长的那根绿线为 y ,而较短的绿线即为 ,我们来看看绕它们旋转的情况分别是怎样的(左图为绕y旋转,右图为绕旋转)
答案是:再做 操作时,旋转的y轴就是原先的 y=(0,1,0),即上左图的情况。因为 的旋转矩阵是根据 y=(0,1,0)的情况计算出来了,因此使用该矩阵计算时,无论物体属于一个什么角度,计算出来的结果都是根据 y=(0,1,0)这个轴进行逆时针旋转的结果(注:(0,0,0)为物体的中心点)。
我们可以称x轴方向为(1,0,0),y轴方向为(0,1,0),z轴方向为(0,0,1)的三个轴为世界坐标轴,它们不根据物体的旋转而改变。而会根据物体自身的坐标轴会根据物体的旋转而改变,例如上诉中的,我们可以称之为模型坐标轴。(自己按照unity常用的说法瞎定义了,懂原理就好。)
因此上诉的两个旋转操作都是按照世界坐标轴来进行的,这种我们称之为外旋,表达式 ,我们可以称之为 x-y外旋 操作。那么内旋就是使用模型坐标轴来做旋转操作咯,那么如果我想要实现先绕x轴旋转 度,在绕旋转后的模型坐标轴的y轴()旋转 (即 x-y内旋 操作),那么应该怎么计算呢?
首先,第一步是绕x轴旋转,此时物体还没发生旋转,因此模型坐标的x轴等于世界坐标的x轴,因此我们依旧可以使用 矩阵。接着我们要绕 =(0,cos,sin) 旋转,这里我们需要将其进行拆解(类似于上一篇中二维空间绕空间中任意一点旋转那样,拆解成先把任意点移到原点,然后旋转,然后再把改点移回去),先把 绕世界坐标的x轴旋转 度,使其与世界坐标的y轴重叠,然后使用 矩阵进行旋转 角度,最后再绕世界坐标的x轴旋转,是旋转轴回到(0,cos,sin)方向。
因此 x-y内旋操作即为:
- 绕世界坐标x轴旋转度,对应矩阵
- 绕世界坐标x轴旋转度,对应矩阵
- 绕世界坐标y轴旋转度,对应矩阵
- 绕世界坐标x轴旋转度,对应矩阵
可以发现第一第二步可以抵消,因此x-y内旋操作等价于先绕世界坐标y轴旋转度再绕世界坐标x轴旋转度,即 x-y内旋 等于 y-x外旋。
上诉过程用矩阵来表达的话,我们知道绕世界坐标x轴旋转度即为绕世界坐标x轴旋转度的逆变换,因此其矩阵即为的逆矩阵,为,因此矩阵如下
x-y内旋 = = (因为 等于单位矩阵) = y-z外旋
同理也可得出 x-z内旋等于z-x外旋,z-y内旋等于y-z内旋等等。
三者结合使用
知道上面这些原理后,我们再进一步,来理解下面表达式
同样的,上面式子可以称之为 x-y-z外旋 操作,即先绕世界坐标的x轴旋转度,然后在绕世界坐标的y轴旋转度,最后绕世界坐标的z轴旋转度。带入可得:
那么它是否和前面一样 x-y-z外旋 等于 z-y-x内旋 呢?答案是肯定的,我们来看下推导。
z-y-x内旋,重点在于如何把z-y操作后模型坐标x轴移动到世界坐标的x轴上,通过前面我们知道 z-y 内旋等于 y-z 外旋,因此旋转后的模型坐标x轴即执行了 操作,此时的模型坐标x轴,我们标记为。因此若我们要使得变回与世界坐标的x重叠,只需要执行一下相反的操作即可,即把先绕z轴旋转度,然后在绕y轴旋转度,对应矩阵为。
因此z-y-x内旋可以分解为如下几步骤:
- 先将其分解为 y-z外旋 + x内旋
- 做y-z外旋,对应矩阵
- 做y-z外旋的逆操作,是到世界坐标x轴上,对应矩阵
- 绕世界坐标x轴旋转,对应矩阵
- 把归位,即再做一次y-z外旋操作,对应矩阵
连起来可得公式为:
z-y-x内旋 = = () = x-y-z外旋
可得结论:所有外旋操作等于与其操作顺序相反的内旋操作。
排列组合
我们一共可以得到以下六种排列组合。不同的组合得到值是不一样的,因为 等。
- x-y-z外旋(等价于z-y-x内旋)
- x-z-y外旋(等价于y-z-x内旋)
- y-x-z外旋(等价于z-x-y内旋)
- y-z-x外旋(等价于x-z-y内旋)
- z-x-y外旋(等价于y-x-z内旋)
- z-y-x外旋(等价于x-y-z内旋)
上面的这些旋转方式也就是我们常用的欧拉角旋转。
对于上面这些排列组合,很多会解释为每个轴对应的层级关系,例如x-y-z外旋,转动x后,y和z在之后的计算用的还是世界坐标轴,就好像x的转动和yz没有关系。y和z之间也是一样,转动y后,z还是用世界坐标轴计算,不会因为y的改变而改变。这个就很像所谓的层级关系,即z为最父层,x为最子层,y在中间层,当子层转动的时候,不会影响到父层。反过来也一样,x-y-z外旋等于z-y-x内旋,父层的z转动会影响y和x(内旋用的模型坐标轴)。
欧拉角的维基百科:https://en.wikipedia.org/wiki/Euler_angles
万向锁(Gimbal Lock)
关于万向锁是什么,看这个视频应该就可以明白了:https://v.youku.com/v_show/id_XNzkyOTIyMTI=.html
简单来说上诉六个组合的操作,只要把中间那个操作的旋转角度设为90度的整数倍,就会触发万向锁。
我们可以从内旋的角度很好理解,以z-y-x的内旋为例子,当我们做第一步操作时,即绕模型坐标的z轴旋转度,无论怎么旋转,z轴都不会改变且等于世界坐标的z轴,但是模型坐标的x,y轴会跟着旋转变换。此时我们再做第二步操作,即绕模型坐标的y轴逆时针旋转 度,当 时,我们会发现此时的x轴会和做第一步操作时的z轴(同时也是世界坐标的z轴)处于同一条直线,方向相反。那么当我们再做第三步操作时,即绕x轴旋转,那就等于在绕世界坐标的z轴旋转,就等同于第一步操作,只不过方向相反。这就是万向锁了,即欧拉角有两个角的旋转都在绕同一个轴在旋转。
接着我们来从数学的角度分析一下:假设我们使用x-y-z外旋,对应的矩阵即为 :
此时我们把的值设为90,可得下面矩阵:
即:
最终得到:
即无论我们的和取何值, 永远等于 。
怎么理解 永远等于 呢?当我们做一次绕世界坐标y轴逆时针旋转90度时,此时(1,0,0)即会变为(0,0,1),即 等于 (=90的效果)。而永远等于就说明之后的z轴不会发生改变,什么情况下不会改变呢?那就是绕着世界坐标轴的z轴做旋转,即我们修改和的值会发现,只绕着世界坐标轴的z轴在旋转。
总结:每个内旋组合,将第二个轴的旋转角度设为90度或其整数倍时,就会触发万向锁,此时无论第一个轴或第三个轴的旋转角度为多少,都是在绕第一个轴所对应的世界坐标轴做旋转,从而失去了一个方向(第三个轴)的旋转能力。
绕任意轴旋转
前面我们说提到的是欧拉角旋转,若我们想要计算绕某个轴旋转,应该如何计算呢?
绕xy平面上过原点的轴旋转
我们先从简单的来,假如有个轴,它在xy平面上,并且经过原点,那么绕该轴做逆时针旋转应该如何来解?首先因为这个轴在xy平面且经过原点,因此通过绕z轴旋转某个角度(设 度)即可将该轴转到原y轴的方向上,然后绕该轴的逆时针旋转即是原先绕y轴逆时针旋转,旋转完成后再绕z轴旋转 - 度即可。这点和我们前面讲欧拉角旋转时是一样的,使用公式表达即为:
合并得
上诉矩阵即为三维空间中,绕xy平面上过原点的任意轴逆时针旋转 度的矩阵,其中 为该轴与y轴的夹角。
当然了,我们一般会给定的是一个轴(x,y,z)这样,而不是一个轴与某个向量的夹角,那么假设在xy平面上的某个轴为(x,y,0),那么绕这个轴旋转度的矩阵应该是多少呢?
同样的,我们设(x,y,0)与y轴的夹角为度,那么可得: 与 ,看着很麻烦是不是,那么假设我们的(x,y,0)是单位向量呢?那么,即 ,, 所以我们第一步先把给定的轴的向量转换为单位向量。
接着我们将它们带入到上面的矩阵中可得:
再根据矩阵的加法定则,把 sin , cos,和常量 来个质壁分离,可得:
再根据矩阵和常数的乘法,我们可以把sin 和 cos 提取出来,可得到:
因为前面说过,转为了单位向量,所以: 和 ,进一步的简化为:
可以发现,上面中间的那个矩阵,和最左边的那个矩阵很相似,其实就是单位矩阵减去左边的那个矩阵:
换下位置可以得到:
单位矩阵我们标记为 ,而 其实就是 向量 和其转置 的积(该例子中,z=0):
结论:若我们要绕xy平面上的某个轴 A=(x,y,0) 旋转度(其中A为单位向量),其公式为:
前面我们是把xy平面的轴转到y上,当然我们也可以转到x上,然后使用x的旋转,得到最终结果是一样的。举一反三也可以计算绕xz平面或yz平面的轴旋转,不过也不用举了,下面我们之间来看绕xyz空间中的轴旋转的公式。
绕空间中过原点的轴旋转
前面我们是绕 (x,y,0)旋转,最终我们想要的肯定是绕(x,y,z)的旋转公式,那么绕过原点的一个轴 A=(x,y,z) 旋转 度(其中A为单位向量),其公式应该是什么?
其实原理都是一样的,我们要先把这个轴搞到世界坐标y轴上,然后执行旋转操作,最后把这个轴归位。分如下几步操作:
- 通过绕世界坐标y轴旋转将该轴转到xy平面上,其中夹角 为该轴在xz平面上的投影(x,0,z)与x轴(1,0,0)的夹角。
- 通过绕世界坐标z轴旋转将该轴转到y轴上,其中夹角 为该轴(x,y,z)与y轴(0,1,0)的夹角。(因为第一步操作时,我们的旋转轴A与y轴的夹角不会发生变换。对边为)
- 绕世界坐标y轴旋转 度
- 2操作的逆操作
- 1操作的逆操作
可以得到如下公式:
根据三角函数可以得到 ,,,,我们设, (m*n =1),将它们带入上面公式,得到:
进一步得到:
因为m*n =1所有再简化为:
全部相乘可得:
把 sin , cos,和常量拆分出来分别可得:
常量为: 就是我们 的值
cos 为:
第一项带入n值得到:,我们来对进行简化,如下:
所以
第三项带入n值得到:
第五项带入m值得到:
第七项等价于第三项。
最后一项带入n值得到:,和第一项的解法类似,最终得到:
所以简化后的矩阵为:
sin 为:
其中由于,提取sin,可得:
结论:若我们要绕xy平面上的某个轴 A=(x,y,z) 旋转度(其中A为单位向量),其公式为:
若z=0,就是我们上面在xy平面上的轴旋转,同理y=0就是在xz平面上的轴旋转,x=0就是yz平面上的轴旋转。
绕空间中不过原点的轴旋转
前面我们的轴都是规定是过原点的,若我们想要绕不过原点的某个轴旋转,其实一样的思路,先把这个轴使用平移变换移动到原点处,然后做上面的操作,最后把这个轴移回去即可。因为是平移操作,使用矩阵时要使用齐次坐标的矩阵,推导就不多描述了,懂原理就肯定能算出来!
旋转矩阵都为正交矩阵
关于正交矩阵的定义可以查看前面矩阵相关的文章。
我们知道旋转矩阵的值即为(1,0,0),(0,1,0),(0,0,1)三个向量旋转后的值,我们假设旋转后的值分别为 ,,,可得旋转矩阵:
根据正交矩阵的定义可得 ,根据 我们可得 的值如下:
让我们来验证下,如下:
因为单位向量旋转后依旧是单位向量,因此 。同时原本互相垂直的三个轴旋转后依旧互相垂直,因此(向量点乘的定义),其他几个位置的值也同理,因此可得结果为单位矩阵,旋转矩阵为正交矩阵没有问题。
这个性质非常重要,因为旋转矩阵是正交矩阵,所以旋转变换的逆变换对应的矩阵即为旋转矩阵的转置,即 。
四元数旋转
我们先来说说上诉两种旋转的缺点:
欧拉角旋转:
- 有很多种顺序,不同的顺序结果还不一样
- 万向锁的问题
- 无法实现平滑的插值,例如旋转15度的矩阵和旋转25度的矩阵相加除以2得到的矩阵并不是旋转20度的矩阵。或者说当我们的旋转角度均匀/平滑的增长时对应的旋转矩阵并不是均匀的增长。这些都是因为三角函数是曲线的。
- 计算起来需要三个矩阵,在空间和时间上花费都较大
绕任意轴旋转:
- 计算复杂
- 无法实现平滑的插值
因此又衍生出了一种旋转,即四元数旋转,它最大的优势就是可以实现平滑的插值,以及不会产生万向锁的问题,缺点就是理解起来比较困难。
四元数
接下来我们先来了解一下四元数是什么,以及他的一些运算法则。
一个四元数可以表示为 q = w + xi + yj + zk,其中w,x,y,z为实数,i,j,k三者为复数,即 ,因此四元数的实部为w,虚部为xi,yj和zk。
此外三个虚数还有如下关系:ij=k,ji=-k,jk=i,kj=-1,ki=j,ik=-j。这是不是和我们的坐标系叉乘一样(x轴叉乘y轴等于z轴等等)
除了上面的表达式外,四元数还有一种我们更熟悉的写法,为 q = ((x,y,z),w),其中(x,y,z)代表一个向量,即 或者写成 。
若我们空间中的一个向量(1,2,3),使用四元数表示即为 0+1i+2j+3k 或者是 ((1,2,3),0)。
因此一个向量看作为一个实部为0的四元数,而一个虚部为0的四元数即为一个实数。
四元数的模
类似于向量的模,四元数q的模即为:
四元数的乘法
设我们有两个四元数,分别为 和 ,那么他们相乘的结果为:
根据该式子我们也可发现 (不满足交换律)因为
根据向量点乘,可得
根据向量叉乘,可得
根据向量的数量积,可得
所有全部结合起来可得:
四元数的加法
四元数的各部位相加即可,满足交换律和结合律:
四元数的点积
类似于向量的点积,如下:
因此也可知:
共轭四元数
四元数q的共轭四元数,常标记为 ,其值为 。共轭四元数即为矩阵的共轭转置。根据四元数的乘法我们可得:
由于 所以
最终可得:
四元数的逆
一个非零四元数q的逆,常标记为 ,其值为:
很明显可得:
旋转
了解了四元数以及四元数的运算后,我们来看看怎么用四元数来表示旋转。前面我们说过变换的本质是函数,使用四元数表达也是一样的,即从一个四元数通过一个函数变成一个新的四元数。而这个用于表达旋转的函数即为:
其中p为我们的输入向量对应的四元数, 为旋转后的向量对应的四元数,而 q 的值为 ,xyz为我们旋转轴的值(需要是单位向量,下面有解释), 为我们的旋转角度。
根据前面所知 ,我们可以求得 ,emmmm,很复杂,但是假如我们的旋转轴是单位向量呢?那么,可得 ,因此 。
例如我们的输入向量为(1,0,0),那么它对应的四元数即为((1,0,0),0),此时我们想将它绕(0,1,0)旋转90度,就可得到如下公式
通过四元数的乘法,我们来计算一下:
首先因为 带入可得
然后先求前两项相乘的结果
将前两项的结果乘以后一项得
可得旋转后的向量为 (0,0,-1) ,结果正确!
备注:相关其他知识待后续补充
Unity与旋转
注:虽然是说图形学基础,但是个人学习的目的主要还是更深入理解Unity,因此顺便也记录一些其中与Unity相关的知识点。
欧拉角旋转
在Unity中,我们在Inspector界面中设置Transform的Rotation属性,或者在代码里设置 transform.localEulerAngles ,这两种方法都是使用的欧拉角旋转。
此外我们还要注意,Unity使用的是左手坐标系而非前面我们一直所举例用的右手坐标系。
左手坐标系:
前面我们提到欧拉角旋转有6中排列组合,那么Unity使用的是哪种呢?在Transform的Rotate方法中,有如下一段注释:
The implementation of this method applies a rotation of zAngle degrees around the z axis, xAngle degrees around the x axis, and yAngle degrees around the y axis (in that order).
因此我们可以知道,Unity使用的是z-x-y外旋,也就是y-x-z内旋。
如何确定是正确的呢?我们可以创建一个Cube,然后通过按照y-x-z的顺序来调整值,这个是内旋的顺序,即每次旋转都是按照模型坐标来旋转的,因此每次旋转对应的模型旋转轴不会发生改变。如下:
既然是使用欧拉角旋转,那么同样会存着万向锁的问题,因为是z-x-y的顺序,那么我们只需要把x轴旋转90度,就可触发万向锁,如图无论怎么修改y和z,都是在绕模型坐标的x轴或者说是世界坐标的y轴在旋转。
同时我们还要注意,像图中,我们是先设置好x轴的旋转,然后再设置y或者z的旋转,这并不代表unity先旋转了x轴,再旋转其他轴。实际上无论我们怎么先后设置xyz三个轴的旋转值时,Unity始终都是要按照z-x-y的顺序来从初始位置开始旋转。这点也很好理解,因为顺序不一样的话,结果也是不一样的。
绕任意轴旋转
Transform中提供了Rotate和RotateAround两种方法用于绕任意轴旋转。
Rotate
有如下三个参数,第一个参数为旋转轴的向量,第二个参数为旋转角度,第三个参数决定旋转轴的起点(默认为Space.Self即起点为物体的中心点,否则为世界坐标的原点)。
public void Rotate(Vector3 axis, float angle, [DefaultValue("Space.Self")] Space relativeTo)
{if (relativeTo == Space.Self)this.RotateAroundInternal(this.transform.TransformDirection(axis), angle * ((float) Math.PI / 180f));elsethis.RotateAroundInternal(axis, angle * ((float) Math.PI / 180f));
}
例如我们想绕过物体中心点的方向为(1,1,1)的轴旋转,使用下面方法即可
transform.Rotate(new Vector3(1, 1, 1), Time.deltaTime * 30);
效果如下:
RotateAround
若想自定义旋转轴的起点,则使用RotateAround方法即可
public void RotateAround(Vector3 point, Vector3 axis, float angle)
第一个参数即为旋转轴的起点,需要注意的是该起点的值为世界坐标的值,而不是相对于物体中心的偏移量。
若想绕起点在世界坐标(1,0,0)的向量(1,1,1)旋转,则代码为:
transform.RotateAround(new Vector3(1,0,0), new Vector3(1, 1, 1), Time.deltaTime * 30);
效果图如下(物体中心在世界坐标(0,0,0)上):
图形学知识基础:三维变换,旋转(欧拉角旋转与万向锁,绕任意轴旋转,四元数)相关推荐
- 三维坐标点绕任意轴旋转的新坐标计算
任意轴可以用一个起点一个方向向量来表示.那么绕任意轴旋转就可以先将此轴移到通过原点,然后再旋转,再将旋转完的新坐标做反向平移. 则问题化为 计算绕通过原点的向量旋转任意角度后的新点.假设单位向量为(r ...
- D3D绕任意轴旋转推导过程及结论
D3D绕任意轴旋转推导及结论 By czg1989 date:2012-4-24 其实之前一直是记下公式的,今天看书的时候就推导了一下 首先假定任意旋转轴穿过原点,如果不穿过,通过平移就可以搞定.记 ...
- CocosCreator | 绕任意轴旋转/绕任意点旋转/平滑旋转/自定义环形体、胶囊体/面向目标位置
01 效果演示 Cocos Creator 版本:3.4.1 该 demo 演示了行星自转(绕任意轴旋转).行星公转(绕任意点旋转).镜头拉近/复位(平滑旋转).行星环(自定义环形体).行星轴(自定义 ...
- open3d显示pcd点云并读取任意点的坐标+生成点云绕任意轴旋转的transformation matrix
为了对点云进行旋转操作,达到各点云之间不对齐的效果,找到了生成点云绕任意轴旋转的矩阵的代码. 链接: https://blog.csdn.net/u010848251/article/details/ ...
- VTK笔记-几何变换-绕任意轴旋转
绕任意轴旋转思路 中心轴与坐标轴平行 1.将旋转轴平移与坐标轴重合,物体也做平移操作: 2.物体绕坐标轴旋转: 3.执行步骤1的逆操作,将旋转轴平移回到原来位置,物体也对应平移: 中心轴与 ...
- 图形学知识基础:变换与矩阵的关系,齐次坐标
何为变换 首先是两个参考视频: 视频1:现代计算机图形学入门-闫令琪(第三章:变换的介绍) 视频2:线性代数的本质 - 03 - 矩阵与线性变换 在生活中,或者说在我们开发游戏的时候,会碰见很多很多的 ...
- Unity3D鼠标&Touch拖拽控制节点绕任意轴旋转的实现
这个拖拽最明显的一个优点就是有阻尼的效果 阻尼(damping)是指摇荡系统或振动系统受到阻滞使能量随时间而耗散的物理现象 using UnityEngine; using System.Collec ...
- 旋转——绕原点二维旋转,绕任意点的二维旋转,三维基本旋转,绕任意轴的三维旋转
1 简介 计算机图形学中的应用非常广泛的变换是一种称为仿射变换的特殊变换,在仿射变换中的基本变换包括平移.旋转.缩放.剪切这几种.本文以及接下来的几篇文章重点介绍一下关于旋转的变换,包括二维旋转变换. ...
- 绕任意向量旋转分解到坐标系旋转
如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:129518033 一.原理解析 假设向量为(a,b,c),旋转角度为θ. 绕任意向量旋转的过程分解如下: ...
- 沿任意轴旋转及其推导
原博客地址:https://blog.csdn.net/zsq306650083/article/details/8773996 1. 2D中绕原点旋转 设基向量p,q和r分别是朝向+x,+y和+z方 ...
最新文章
- ccnp bcmsn 高级交换学习笔记2
- Spring Boot与Docker||Docker基本使用、Docker环境||安装Docker
- C#协变和逆变 - 译
- 类似wordpress的网站模板
- sqlserver中无ldf文件附加数据库
- SAP Spartacus directive学习笔记
- Demo分享丨看ModelArts与HiLens是如何让车自己跑起来的
- 手机modem开发(15)---FT 测试天线注意事项
- 吴恩达机器学习总结四:Octave语法
- 微信公众帐号开发教程第13篇-图文消息全攻略
- ❤️Spring的静态、动态代理模式
- c++ 输出格式控制
- 阿里云服务器ECS云盾提醒网站被WebShell木马后门分析与对策
- 关于asp.net中文文件名超长的下载问题
- 【游戏开发3D数学笔记】1.有话说在前面
- 学习区块链经典教程:区块链技术与应用
- 细说ConcurrentHashMap扩容规则
- b 站视频下载神器合集,支持电脑和手机端
- 阜南一中2021高考成绩查询,高考喜报出炉!阜南一中、阜阳一中、三中……取得了怎样的好成绩?(附名单)...
- 简单大学生静态HTML网页作品 HTML5+CSS大作业——圣诞节节日(7页) 带轮播特效