嘎嘎詳細的三維變換詳細講解,包括視圖變換、投影變換等,超級通俗易懂!

前置二維空間的各種變換筆記:二維變換

三維空間中的齊次坐標

  • 從二維變換開始引申,可得到三維中的一個點的表達方式為 ( x , y , z , 1 ) ? (\mathbf{x}, \mathbf{y}, \mathbf{z}, 1)^{\top} (x,y,z,1)?,也就是w=1,而三維的向量則表達為 ( x , y , z , 0 ) ? (\mathbf{x}, \mathbf{y}, \mathbf{z}, 0)^{\top} (x,y,z,0)?,也就是w=0
  • 由于三維空間的一個點是上述格式的,若其中的w由于兩點相加或者其他原因超過了1,則我們令這個點的xyz都除以w,那么w就會變成1了,也就是xyz所表達的位置坐標為 ( x / w , y / w , z / w ) (x / w, y / w, z / w) (x/w,y/w,z/w)
  • 而在三維空間中的齊次變換矩陣則如 ( x ′ y ′ z ′ 1 ) = ( a b c t x d e f t y g h i t z 0 0 0 1 ) ? ( x y z 1 ) \left(\begin{array}{l} x^{\prime} \\ y^{\prime} \\ z^{\prime} \\ 1 \end{array}\right)=\left(\begin{array}{lllc} a & b & c & t_x \\ d & e & f & t_y \\ g & h & i & t_z \\ 0 & 0 & 0 & 1 \end{array}\right) \cdot\left(\begin{array}{l} x \\ y \\ z \\ 1 \end{array}\right) ?xyz1? ?= ?adg0?beh0?cfi0?tx?ty?tz?1? ?? ?xyz1? ?所示
  • 其中矩陣的abcdefghi表達為線性變換,tx、ty、tz表達為平移變換,總體表達為一種仿射變換。
  • 同樣,矩陣的最后一行也是(0, 0, 0, 1)
  • 其中線性變換和平移變換的執行順序是先執行線性變換,再執行平移變換,具體可以從我們二維仿射變換公式看 ( x ′ y ′ ) = ( a b c d ) ? ( x y ) + ( t x t y ) \binom{x^{\prime}}{y^{\prime}}=\left(\begin{array}{ll} a & b \\ c & d \end{array}\right) \cdot\binom{x}{y}+\binom{t_x}{t_y} (yx?)=(ac?bd?)?(yx?)+(ty?tx??),先乘線性變換矩陣,再加平移變換。

三維齊次變換

  • 由二維向外引申,便可得到三維的各種變換矩陣形式
  • 縮放變換: S ( s x , s y , s z ) = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) \mathbf{S}\left(s_x, s_y, s_z\right)=\left(\begin{array}{cccc} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{array}\right) S(sx?,sy?,sz?)= ?sx?000?0sy?00?00sz?0?0001? ?
  • 平移變換: T ( t x , t y , t z ) = ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) \mathbf{T}\left(t_x, t_y, t_z\right)=\left(\begin{array}{cccc} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{array}\right) T(tx?,ty?,tz?)= ?1000?0100?0010?tx?ty?tz?1? ?
  • 旋轉變換:
    • 繞x軸旋轉: R x ( α ) = ( 1 0 0 0 0 cos ? α ? sin ? α 0 0 sin ? α cos ? α 0 0 0 0 1 ) \mathbf{R}_x(\alpha)=\left(\begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & \cos \alpha & -\sin \alpha & 0 \\ 0 & \sin \alpha & \cos \alpha & 0 \\ 0 & 0 & 0 & 1 \end{array}\right) Rx?(α)= ?1000?0cosαsinα0?0?sinαcosα0?0001? ?
    • 繞y軸旋轉: R y ( α ) = ( cos ? α 0 sin ? α 0 0 1 0 0 ? sin ? α 0 cos ? α 0 0 0 0 1 ) \mathbf{R}_y(\alpha)=\left(\begin{array}{cccc} \cos \alpha & 0 & \sin \alpha & 0 \\ 0 & 1 & 0 & 0 \\ -\sin \alpha & 0 & \cos \alpha & 0 \\ 0 & 0 & 0 & 1 \end{array}\right) Ry?(α)= ?cosα0?sinα0?0100?sinα0cosα0?0001? ?
    • 繞z軸旋轉: R z ( α ) = ( cos ? α ? sin ? α 0 0 sin ? α cos ? α 0 0 0 0 1 0 0 0 0 1 ) \mathbf{R}_z(\alpha)=\left(\begin{array}{cccc} \cos \alpha & -\sin \alpha & 0 & 0 \\ \sin \alpha & \cos \alpha & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right) Rz?(α)= ?cosαsinα00??sinαcosα00?0010?0001? ?
    • 上述旋轉都是簡單的繞軸旋轉,但是如果是一般性的旋轉又該怎么處理呢?
    • 圖形學有一個大佬,就寫了一個矩陣,可以把任意一個軸的旋轉寫成一個矩陣,這個旋轉公式就是著名的Rodrigues旋轉公式,公式為 R ( n , α ) = cos ? ( α ) I + ( 1 ? cos ? ( α ) ) n n T + sin ? ( α ) ( 0 ? n z n y n z 0 ? n x ? n y n x 0 ) ? N \mathbf{R}(\mathbf{n}, \alpha)=\cos (\alpha) \mathbf{I}+(1-\cos (\alpha)) \mathbf{n} \mathbf{n}^T+\sin (\alpha) \underbrace{\left(\begin{array}{ccc} 0 & -n_z & n_y \\ n_z & 0 & -n_x \\ -n_y & n_x & 0 \end{array}\right)}_{\mathbf{N}} R(n,α)=cos(α)I+(1?cos(α))nnT+sin(α)N ?0nz??ny???nz?0nx??ny??nx?0? ???
    • 其中n代表要繞著的旋轉軸向量

圖形變換

  • 模型變換:類比于在一個場景中,模型的擺放,也就是拍照時所拍的物體放在哪

  • 視圖變換:類比于,找到一個相機的角度,也就是相機在哪里拍照

  • 投影變換: 從模型和視圖變換之后做一個3d到2d的投影,類似與相機和拍攝物體都確定好了,拍照的這么個過程

視圖變換如何做?

  • 也就是怎么定義一個相機視角

  • 首先需要相機的位置 e ? \vec{e} e ,其次還需要相機的朝向 g ^ \hat{g} g^?,也就是往哪看,最后需要一個向上方向 t ^ \hat{t} t^來定義相機是往上看還是往下看。至此,即可確定一個相機的視角了。

  • 由于只要能保住相機和其所拍攝的物體所有的相對位置都是固定的,那么無論相機和這個物體被怎樣移動,那么最后拍攝下來的照片應該都是一樣的才對,所以為了方便運算,有一個約定俗成的規定,就是將相機永遠擺放至原點

  • 假設當前相機視角如圖所示,應該怎樣將其變換到原點出呢

    image-20240710090850635

    image-20240710091101643

    • 首先做一個平移變換將相機移動到原點
    • 再將相機朝向 g ^ \hat{g} g^?做旋轉變換移動到-Z上
    • 最后將向上朝向 t ? \vec{t} t 移動到Y上,那么 g × t g \times t g×t也就自動朝向X了
    • 我們可以定義整個變換矩陣為M,也就是用M來表達剛剛的所有操作,那么就有 M view? = R view? T view? M_{\text {view }}=R_{\text {view }} T_{\text {view }} Mview??=Rview??Tview??
    • 也就是先乘平移變換再乘旋轉變換即可得到總的M變換矩陣,而這個變換矩陣T很好寫,為 T view? = [ 1 0 0 ? x e 0 1 0 ? y e 0 0 1 ? z e 0 0 0 1 ] T_{\text {view }}=\left[\begin{array}{cccc} 1 & 0 & 0 & -x_e \\ 0 & 1 & 0 & -y_e \\ 0 & 0 & 1 & -z_e \\ 0 & 0 & 0 & 1 \end{array}\right] Tview??= ?1000?0100?0010??xe??ye??ze?1? ?,也就是將自己的所在點各減去自己點離原點的距離即可
    • 而旋轉R矩陣則相對較難,很難直觀的知道怎樣從一個軸變換到X、Y、-Z軸上,但是我們如果反過來思考,如果要把X、Y、-Z軸變換到某一個軸上,就很簡單了,這就是前文提到的逆變換,而我們知道,逆變換矩陣是一個正交矩陣,而正交矩陣有一個性質就是他的逆是他自己的轉置 R ? θ = R θ T \mathbf{R}_{-\theta}=\mathbf{R}_{\theta}^T R?θ?=RθT?,于是我們只需要求出X、Y、Z如何變換到 g × t g\times t g×t t t t ? g -g ?g上,再對該矩陣轉置一下,就能得到從 g × t g\times t g×t t t t g g g變換到X、Y、-Z的變換矩陣了。
    • 比如要將X軸 [ 1 0 0 0 ] \begin{bmatrix} 1\\ 0\\ 0\\ 0 \end{bmatrix} ?1000? ?旋轉到 g × t g \times t g×t [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 ] \begin{bmatrix} x_{\hat{g} \times \hat{t} }\\ y_{\hat{g} \times \hat{t} }\\ z_{\hat{g} \times \hat{t} }\\ 0 \end{bmatrix} ?xg^?×t^?yg^?×t^?zg^?×t^?0? ?上,則旋轉矩陣為 [ x g ^ × t ^ 0 0 0 y g ^ × t ^ 0 0 0 z g ^ × t ^ 0 0 0 0 0 0 1 ] \left[\begin{array}{cccc} x_{\hat{g} \times \hat{t}} & 0 & 0 & 0 \\ y_{\hat{g} \times \hat{t}} & 0 & 0 & 0 \\ z_{\hat{g} \times \hat{t}} & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] ?xg^?×t^?yg^?×t^?zg^?×t^?0?0000?0000?0001? ?,同理可得Y、Z軸,將其合并一下,即可得到總的逆旋轉矩陣 R v i e w ? 1 = [ x g ^ × t ^ x t x ? g 0 y g ^ × t ^ y t y ? g 0 z g ^ × t ^ z t z ? g 0 0 0 0 1 ] R_{view}^{-1}=\left[\begin{array}{cccc} x_{\hat{g} \times \hat{t}} & x_t & x_{-g} & 0 \\ y_{\hat{g} \times \hat{t}} & y_t & y_{-g} & 0 \\ z_{\hat{g} \times \hat{t}} & z_t & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] Rview?1?= ?xg^?×t^?yg^?×t^?zg^?×t^?0?xt?yt?zt?0?x?g?y?g?z?g?0?0001? ?,則轉置后的旋轉矩陣為 R v i e w = [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 x t y t z t 0 x ? g y ? g z ? g 0 0 0 0 1 ] R_{view}=\left[\begin{array}{cccc} x_{\hat{g} \times \hat{t}} & y_{\hat{g} \times \hat{t}} & z_{\hat{g} \times \hat{t}} & 0 \\ x_t & y_t & z_t & 0 \\ x_{-g} & y_{-g} & z_{-g} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] Rview?= ?xg^?×t^?xt?x?g?0?yg^?×t^?yt?y?g?0?zg^?×t^?zt?z?g?0?0001? ?,這便得到了從任意軸旋轉到原點X、Y、-Z軸的旋轉矩陣了,再和前面的平移矩陣T相乘,即可得到最終的變換矩陣M。
  • 也就是,只要相機和所拍攝關聯到的物體都按照這個M矩陣進行變換,那么在變換前和變換后所拍攝到的內容應該都是一樣的。

投影變換如何做?

  • 正交投影:投影前后無透視扭曲,即無近大遠小的特性

    image-20240710101540574

    • 而想要將三維物體在無透視變化的情況下投影到二維平面上其實很簡單,只需要去除這個物體的z軸就行了

      image-20240710133905868

    • 假設我們要投影的物體如上所示,可以發現,只要將他倆的z軸去掉,那么剩下的x,y自然就是他在二維平面上的投影。

    • 但是一般情況下,需要先將這個物體通過變換矩陣轉移到原點xy軸的-1到1之間的矩形之中,這樣做的目的是為了簡化后續操作,也就是大家都遵守這套規范,后續api啊各方面的開發就會很簡便。

    • 但是這樣做就會出現一個問題,就是物體的前后信息丟失了,你無法顯示出物體的深度信息,為了解決這個問題,通常會保留下這個z軸,也就是說先將物體通過各種變換轉移到原點處xyz都在-1到1的一個立方體中,這個立方體也叫做標準化空間,這樣的話物體之間的深度信息就會保留下來,也就是x和y坐標會被用來確定物體在屏幕上的位置,而z坐標則用于深度測試等目的。而最終的三維到二維的投影呢則是對這個標準化空間里做一個切片,z坐標被用來進行深度測試和裁剪,而x和y坐標則被用來確定最終在屏幕上的位置。也就是如下圖所示。

      image-20240710135747981

    • 其中l、r為物體的左右(left、right),b、t為下上(bottom、top),f、n為遠近(far,near)。

    • 而將被拍攝物體通過變換矩陣到原點的-1到1的空間內也就很簡單了,先平移變換,再縮放變換即可(對應著上圖的二圖和三圖)。

    • 平移變換可以直接將物體的中心處移動到原點處即可,而物體的中心計算方法就很簡單,x軸的中心就是 r + l 2 \frac{r+l}{2} 2r+l?,yz軸同理,那么將物體最終移動到中心就是自身每個軸減去這個值即可,于是平移變換矩陣為 [ 1 0 0 ? r + l 2 0 1 0 ? t + b 2 0 0 1 ? n + f 2 0 0 0 1 ] \left[\begin{array}{cccc} 1 & 0 & 0 & -\frac{r+l}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{array}\right] ?1000?0100?0010??2r+l??2t+b??2n+f?1? ?

    • 而縮放變換呢就是要將物體規范化到-1到1的空間內,-1到1的長度為2,那么x軸的縮放就是用2除以物體的寬度,也就是 2 r ? l \frac{2}{r-l} r?l2?(具體數學推理就是求一個線性變換y=ax+b,將x等于l和r代入即可得到a和b的值,其中a就是縮放因子,b就是平移因子,最后解的a就是這個2/(r-l)),其他軸同理,于是縮放矩陣為 [ 2 r ? l 0 0 0 0 2 t ? b 0 0 0 0 2 n ? f 0 0 0 0 1 ] \left[\begin{array}{cccc} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] ?r?l2?000?0t?b2?00?00n?f2?0?0001? ?

    • 而最終的正交投影變換矩陣為他倆相乘 M ortho? = [ 2 r ? l 0 0 0 0 2 t ? b 0 0 0 0 2 n ? f 0 0 0 0 1 ] [ 1 0 0 ? r + l 2 0 1 0 ? t + b 2 0 0 1 ? n + f 2 0 0 0 1 ] = [ 2 r ? l 0 0 ? r + l 2 0 2 t ? b 0 ? t + b 2 0 0 2 n ? f ? n + f 2 0 0 0 1 ] M_{\text {ortho }}=\left[\begin{array}{cccc} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & \frac{2}{n-f} & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\left[\begin{array}{cccc} 1 & 0 & 0 & -\frac{r+l}{2} \\ 0 & 1 & 0 & -\frac{t+b}{2} \\ 0 & 0 & 1 & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{array}\right]=\left[\begin{array}{cccc} \frac{2}{r-l} & 0 & 0 & -\frac{r+l}{2} \\ 0 & \frac{2}{t-b} & 0 & -\frac{t+b}{2} \\ 0 & 0 & \frac{2}{n-f} & -\frac{n+f}{2} \\ 0 & 0 & 0 & 1 \end{array}\right] Mortho??= ?r?l2?000?0t?b2?00?00n?f2?0?0001? ? ?1000?0100?0010??2r+l??2t+b??2n+f?1? ?= ?r?l2?000?0t?b2?00?00n?f2?0??2r+l??2t+b??2n+f?1? ?

    • 最后通過這個矩陣M就可以將任意物體規范化到原點處-1到1的標準空間中啦~

  • 透視投影:有近大遠小的特性

    image-20240710101525589

    • 將三維物體通過透視投影到二維平面上有一個辦法,由于透視投影他可以理解成沿著一個點,向外延申出四條線,如上圖,那么所包裹住的物體就是一個四棱臺,而我們知道,正交投影所包裹住的是一個長方體,那我們就可以先將這個四棱臺壓成長方體,再按照正交投影的辦法去變換即可。

      image-20240710144540819

    • 也就是將上面左圖的遠平面在xy軸處壓成近平面的矩形,最終呈現右圖的樣子。顯然,在這個變化當中,近平面的x、y、z都不會發生改變,而遠平面的z和遠平面中心點也不會發生改變。

      image-20240710150424063

    • 如上圖所示((x’,y’,z’)是近平面的點,(x,y,z)是遠平面的點),根據相似三角形原則,若點(x,y,z)想變換到點(x’,y’,z’)上,y和y’的比值一定等于n和z的比值,于是可得 y ′ = n z y y^{\prime}=\frac{n}{z} y y=zn?y,同理可得 x ′ = n x y x^{\prime}=\frac{n}{x} y x=xn?y

    • 也就是說原本(x,y,z,1)和一個矩陣相乘后,會得到(nx/z,ny/z,不知道,1)這樣的向量,而我們知道,在齊次坐標中,一個點同乘任何非0常數,所表達的矩陣依然一致,也就是(nx/z,ny/z,不知道,1)和(nx,ny,不知道,z)他倆所表達的點都是(x,y,z),也就是 M persp? → ortho? ( 4 × 4 ) ( x y z 1 ) = ( n x n y unknown? z ) M_{\text {persp } \rightarrow \text { ortho }}^{(4 \times 4)}\left(\begin{array}{l} x \\ y \\ z \\ 1 \end{array}\right)=\left(\begin{array}{c} n x \\ n y \\ \text { unknown } \\ z \end{array}\right) Mpersp??ortho?(4×4)? ?xyz1? ?= ?nxny?unknown?z? ?

    • 很容易就能得到這個M矩陣為 M persp?ortho? = ( n 0 0 0 0 n 0 0 ? ? ? ? 0 0 1 0 ) M_{\text {persp ortho }}=\left(\begin{array}{cccc} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & 1 & 0 \end{array}\right) Mpersp?ortho??= ?n0?0?0n?0?00?1?00?0? ?

    • 而上述矩陣中的第三行的值可以通過前面所說的兩個條件來計算,就是“近平面的x、y、z都不會發生改變,而遠平面的z和遠平面中心點也不會發生改變。”

    • 設近平面的z軸值為n,也就是上面的M矩陣乘上近平面的(x,y,n,1)后仍然是(x,y,n,1),然后在這個齊次坐標同乘一個n,也就是 M persp? → ortho? ( 4 × 4 ) = ( x y n 1 ) = = ( n x n y n 2 n ) M_{\text {persp } \rightarrow \text { ortho }}^{(4 \times 4)}=\left(\begin{array}{l} x \\ y \\ n \\ 1 \end{array}\right)==\left(\begin{array}{c} n x \\ n y \\ n^2 \\ n \end{array}\right) Mpersp??ortho?(4×4)?= ?xyn1? ?== ?nxnyn2n? ?

    • 那么此時我們將M矩陣的第三行當個向量提取出來,也就是 ( 0 0 A B ) ( x y n 1 ) = n 2 \left(\begin{array}{llll} 0 & 0 & A & B \end{array}\right)\left(\begin{array}{l} x \\ y \\ n \\ 1 \end{array}\right)=n^2 (0?0?A?B?) ?xyn1? ?=n2,前面兩個數之所以為0是因為很明顯最后的這個 n 2 n^2 n2肯定和xy無關,相乘后也就是 A n + B = n 2 A n+B=n^2 An+B=n2

    • 而遠平面的中心點在變換中不會發生改變,設遠平面的z軸值為f,而遠平面中心點則表示為 ( 0 0 f 1 ) \left(\begin{array}{l} 0 \\ 0 \\ f \\ 1 \end{array}\right) ?00f1? ?,同時乘個f,則為 ( 0 0 f 2 f ) \left(\begin{array}{c} 0 \\ 0 \\ f^2 \\ f \end{array}\right) ?00f2f? ?,和前面的 ( 0 0 A B ) \left(\begin{array}{llll} 0 & 0 & A & B \end{array}\right) (0?0?A?B?)相乘后也就是 A f + B = f 2 A f+B=f^2 Af+B=f2,解兩式可得 A = n + f B = ? n f \begin{aligned} & A=n+f \\ & B=-n f \end{aligned} ?A=n+fB=?nf?

    • 這樣就得到了最終的變換矩陣 M persp?ortho? = ( n 0 0 0 0 n 0 0 0 0 n + f ? n f 0 0 1 0 ) M_{\text {persp ortho }}=\left(\begin{array}{cccc} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & -nf \\ 0 & 0 & 1 & 0 \end{array}\right) Mpersp?ortho??= ?n000?0n00?00n+f1?00?nf0? ?,這個矩陣可以將任意物體從透視投影的四棱臺擠壓成正交投影的正方形

    • 最后再按照正交投影的方法來完成后續步驟即可完成透視投影 M persp? = M ortho? M persp? → ortho? M_{\text {persp }}=M_{\text {ortho }} M_{\text {persp } \rightarrow \text { ortho }} Mpersp??=Mortho??Mpersp??ortho??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43101.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43101.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43101.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

插入排序算法(C語言版)

直接插入排序 插入排序(insert sort)是一種簡單的排序算法,它的工作原理與手動整理一副牌的過程非常相似。 具體來說,我們在未排序區間選擇一個基準元素,將該元素與其左側已排序區間的元素逐一比較大小,并…

如何用 Python 繞過 cloudflare(5秒盾) 抓取數據:也不是很難嘛!

大家好!我是愛摸魚的小鴻,關注我,收看每期的編程干貨。 逆向是爬蟲工程師進階必備技能,當我們遇到一個問題時可能會有多種解決途徑,而如何做出最高效的抉擇又需要經驗的積累。本期文章將以實戰的方式,帶你全面了解 cloudflare(5秒盾) 以及如何繞過使用 cloudflare 服務…

(自用)gtest單元測試

gtest是Google的一套用于編寫C測試的框架,可以運行在很多平臺上(包括Linux、Mac OS X、Windows、Cygwin等等)。基于xUnit架構。支持很多好用的特性,包括自動識別測試、豐富的斷言、斷言自定義、死亡測試、非終止的失敗、生成XML報…

Mybatis的優缺點及適用場景?

目錄 一、什么是Mybatis? 二、Mybatis框架的特點 三、Mybatis框架的優點? 四、MyBatis 框架的缺點? 五、MyBatis 框架適用場合? 六、代碼示例 1. 配置文件 mybatis-config.xml 2. 映射文件 UserMapper.xml 3. Java 代碼…

QT TCP網絡通信編程

學習目標: TCP網絡通信編程 前置環境 運行環境:qt creator 4.12 學習內容 一、TCP 協議基礎知識: TCP 是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。TCP 擁塞控制算法包括慢啟動、擁塞避免、快速重傳和快速恢復。TCP 通信需要建立連接,Qt 提供 QTcp…

linux 查看歷史命令列表來訪問之前的內容的命令是:history

在Linux中,要查看歷史命令列表以訪問之前的內容,你可以使用history命令。這個命令會顯示你當前shell會話(或者,如果你指定了參數,可能是所有會話)中執行過的命令列表。 基本用法 簡單地輸入history并按下…

設計模式使用場景實現示例及優缺點(結構型模式——代理模式、外觀模式)

結構型模式 代理模式(Proxy Pattern) 代理模式(Proxy Pattern)是一種結構型設計模式,它通過引入一個代理對象來控制對另一個對象的訪問。這個代理對象可以為被代理的對象提供額外的功能,例如訪問控制、延…

力扣844.比較含退格的字符串

力扣844.比較含退格的字符串 棧模擬 class Solution {public:bool backspaceCompare(string s, string t) {int n s.size(),m t.size();stack<char> s1,s2;for(int i0;i<n;i){s1.push(s[i]);if(s[i] #){if(s1.size() 1) s1.pop();else s1.pop(),s1.pop();}}for(i…

利用Python的sympy包求解一元多次方程

一元1次方程 import sympy as sp # 導入sympy包 x sp.Symbol(x) # 定義符號變量 f 2*x -8 # 定義要求解的一元1次方程 x sp.solve(f) # 調用solve函數求解方程 x[4]一元2次方程 import sympy as sp # 導入sympy包 x sp.Symbol(x) # 定義符號變量 f …

網絡安全合規建設

網絡安全合規建設 一、法律安全需求基本合規&#xff08;1&#xff09;《網絡安全法》重要節點等級保護政策核心變化 二、安全需求 業務剛需&#xff08;1&#xff09;內憂&#xff08;2&#xff09;外患 三、解決方法&#xff08;1&#xff09;總安全戰略目標圖&#xff08;2&…

廣匯汽車:救得起來嗎?

五折奔馳、六折寶馬...BBA們“腰斬式”大降價后正在引發連鎖反應。 國內第二大汽車經銷商——廣匯汽車&#xff0c;還好嗎&#xff1f; 受新能源品牌沖擊&#xff0c;近年來奔馳、寶馬等豪華燃油品牌銷量低迷&#xff0c;紛紛開啟降價模式&#xff0c;首當其沖的就是以廣匯汽車…

使用Python實現深度學習模型:跨平臺模型移植與部署

引言 隨著深度學習技術的快速發展,模型的跨平臺移植與部署變得越來越重要。無論是將模型從開發環境移植到生產環境,還是在不同的硬件平臺上運行,跨平臺部署都能顯著提高模型的實用性和可擴展性。本文將介紹如何使用Python實現深度學習模型的跨平臺移植與部署,并提供詳細的…

QT TCP多線程網絡通信

學習目標&#xff1a; TCP網絡通信編程 學習前置環境 運行環境:qt creator 4.12 QT TCP網絡通信編程-CSDN博客 Qt 線程 QThread類詳解-CSDN博客 學習內容 使用多線程技術實現服務端計數器 核心代碼 客戶端 客戶端&#xff1a;負責連接服務端&#xff0c;每次連接次數1。…

從零開始做題:MP3

題目 給出一個mp3文件 解題 右鍵->selection->save selection->另存為xxx.png即可 8750d5109208213f E:\逐鹿\MISC\tools\MP3Stego_1_1_19\MP3Stego>.\decode -X cipher.mp3 MP3StegoEncoder 1.1.19 See README file for copyright info Input file cipher.mp3…

未來代理IP的發展趨勢:創新、適應和可持續性

你是否好奇&#xff0c;未來代理IP將如何演變以適應日益復雜和全球化的網絡環境&#xff1f;讓我們探討一下代理IP技術在創新、適應性和可持續發展方面的未來前景。 1. 創新技術驅動 未來的代理IP將依托創新技術&#xff0c;如邊緣計算、區塊鏈和深度學習。邊緣計算技術的應用…

AcWing 5458:進水排水問題

【題目描述】 某已經蓄滿水的泳池內裝有 4 個水管。 前 2 個水管是進水管&#xff0c;單位時間的進水量分別為 a,b。 后 2 個水管是排水管&#xff0c;單位時間的排水量分別為 c,d。 請你計算&#xff0c;當 4 個水管同時工作時&#xff0c;是否可能將泳池里的水排干。【輸入格…

53-5 內網代理7 - CS上線不出網主機

靶場搭建: 這里就用之前內網代理的靶場,把web服務器這臺虛擬機關閉掉,用剩下的3臺加kali 各個虛擬機的網絡情況 kali - 可以連接外網win2008(之前的FTP服務器) 可以連接外網 win 7(之前的辦公電腦) 不出網主機 - 無法連接外網win2012 克隆機(之前的域控) - 無法連接…

視頻壓縮文件太大了怎么縮小?3個壓縮方法分享

視頻壓縮文件太大了怎么縮小&#xff1f;當視頻壓縮文件過大時&#xff0c;縮小其大小不僅能節省寶貴的存儲空間&#xff0c;還能顯著提升文件傳輸速度&#xff0c;特別是在網絡條件有限的情況下。通過專業的視頻壓縮軟件&#xff0c;可以有效減少文件體積&#xff0c;使視頻內…

python庫(9):prettytable庫快速實現ASCII表格

下面介紹一個快速制作ASCII表格庫——prettytable&#xff0c;可以方便地制作簡單表格。 1 安裝prettytable pip install -i https://pypi.tuna.tsinghua.edu.cn/simple prettytable 結果如下&#xff1a; 2 代碼實例 from prettytable import PrettyTable table PrettyTa…

【Python系列】深入解析 Python 中的 JSON 處理工具

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…