【重心坐标插值、透视矫正插值】原理以及用法见解(GAMES101深度测试部分讨论)
文章目录
- 1、Barycentric Coordinates(重心坐标)
- 1.1 重心坐标概念
- 1.2 重心坐标计算方式
- 1.3 重心坐标插值
- 2 重心坐标计算公式推导
- 3 透视投影插值矫正
- 3.1 透视矫正后的`深度插值公式`
- 3.2 一个非常重要的透视投影的细节
- 3.2 更通用的:`任意属性插值公式`
1、Barycentric Coordinates(重心坐标)
仅供参考,数学很弱,不保证正确性。。但是看了应该会有收获
1.1 重心坐标概念
以2D为例:
- 三角形内部任何一个点(包括顶点)都可以表示成三个顶点的线性组合。满足以下关系式的三个系数(α,β,γ)就是该点的重心坐标。还有一个限制条件是这三个系数必须非负,否则就在三角形外了
- 简而言之,就是三角形内部一个点(x,y)在重心坐标下的表示就是(α,β,γ)
- 其中三个顶点自己的重心坐标分别是
A:(1,0,0)
B:(0,1,0)
C:(0,0,1)
1.2 重心坐标计算方式
对于三角形内部点P如何计算它的重心坐标
方法1:面积比
- A的系数α:其对应的三角形面积AA(红色部分)占总面积的比值
- B的系数β:其对应的三角形面积AB(黄色部分)占总面积的比值
- C的系数γ:其对应的三角形面积AC(蓝色部分)占总面积的比值
方法2:利用推导出来的公式计算
先说结论,后面第二部分详解推导过程
β=(y−yA)(xC−xA)−(x−xA)(yC−yA)(yB−yA)(xC−xA)−(xB−xA)(yC−yA)γ=(y−yA)(xB−xA)−(x−xA)(yB−yA)(yC−yA)(xB−xA)−(xC−xA)(yB−yA)α=1−β−γ\color{red}\large β=\frac{ (y- y_{\tiny A})(x_{\tiny C} - x_{\tiny A})-(x - x_{\tiny A})(y_{\tiny C} - y_{\tiny A}) }{(y_{\tiny B} - y_{\tiny A})(x_{\tiny C} - x_{\tiny A})-(x_{\tiny B} - x_{\tiny A})(y_{\tiny C} - y_{\tiny A})}\\ \: \\ \large γ=\frac{ (y- y_{\tiny A})(x_{\tiny B} - x_{\tiny A})-(x - x_{\tiny A})(y_{\tiny B} - y_{\tiny A}) }{(y_{\tiny C} - y_{\tiny A})(x_{\tiny B} - x_{\tiny A})-(x_{\tiny C} - x_{\tiny A})(y_{\tiny B} - y_{\tiny A})}\\ \: \\ α=1-β-γ\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:β=(yB−yA)(xC−xA)−(xB−xA)(yC−yA)(y−yA)(xC−xA)−(x−xA)(yC−yA)γ=(yC−yA)(xB−xA)−(xC−xA)(yB−yA)(y−yA)(xB−xA)−(x−xA)(yB−yA)α=1−β−γ
1.3 重心坐标插值
已知重心坐标的计算方法,怎么插值属性呢?
算出来的重心坐标(α,β,γ),其实就相当于一个权重比,直接把对应的VAVBVC换成uv坐标、颜色、法线、深度值、材质属性,V即所求
2 重心坐标计算公式推导
已知2D平面内△ABC△ABC△ABC三个顶点的坐标A:(xA,yA),B:(xB,yB),C:(xC,yC)\large A:(x_A,y_A),B:(x_B,y_B),C:(x_C,y_C)A:(xA,yA),B:(xB,yB),C:(xC,yC)以及三角形内部任意点P的坐标P:(x,y)\large P:(x, y)P:(x,y)
点PPP一定满足两个条件:
{P=αA+βB+γC⋯⋯⋯⋯①α+β+γ=1⋯⋯⋯⋯⋯⋯②\begin{cases} P=\alpha A + \beta B +\gamma C\cdots\cdots\cdots\cdots① \\ \alpha+\beta+\gamma = 1 \cdots\cdots\cdots\cdots\cdots\cdots② \end{cases}{P=αA+βB+γC⋯⋯⋯⋯①α+β+γ=1⋯⋯⋯⋯⋯⋯②
如何根据已知条件计算出α、β、γ\alpha、\beta、\gammaα、β、γ ?
Step 1
公式②代入①,我们可以消除一个未知量(这里我把α先干掉了,101课程中是干掉的γ,过程都是一样的)
P=(1−β−γ)A+βB+γCP = (1-β-γ)A+βB+γCP=(1−β−γ)A+βB+γC
打开括号,合并同类项并简单移项,很容易能得出
P−A=β(B−A)+γ(C−A)⋯⋯⋯⋯③P-A=β(B-A)+γ(C-A)\cdots\cdots\cdots\cdots③P−A=β(B−A)+γ(C−A)⋯⋯⋯⋯③
这个公式,可以按照向量运算来理解,AP→=βAB→+γAC→\overrightarrow {AP} = β\overrightarrow {AB}+γ\overrightarrow {AC}AP=βAB+γAC
【突然发现图中我两个向量写反了。。向量AB和向量AC应该互换一下,我有空再改过来吧】
Step 2
由公式③,将已知点A、B、C、PA、B、C、PA、B、C、P的坐标代入,可得
(x−xAy−yA)=β(xB−xAyB−yA)+γ(xC−xAyC−yA)\large \begin{pmatrix} x - x_{\tiny A} \\y- y_{\tiny A} \end{pmatrix}= β\large\begin{pmatrix} x_{\tiny B} - x_{\tiny A} \\ y_{\tiny B} - y_{\tiny A} \end{pmatrix}+ γ\large\begin{pmatrix}x_{\tiny C} - x_{\tiny A} \\ y_{\tiny C} - y_{\tiny A} \end{pmatrix}(x−xAy−yA)=β(xB−xAyB−yA)+γ(xC−xAyC−yA)
拆开写,可得方程组(两个未知数,两个方程)
{(x−xA)=β(xB−xA)+γ(xC−xA)⋯⋯④(y−yA)=β(yB−yA)+γ(yC−yA)⋯⋯⋅⑤\begin{cases} (x - x_{\tiny A}) =β(x_{\tiny B} - x_{\tiny A})+γ(x_{\tiny C} - x_{\tiny A})\cdots\cdots④\\ (y- y_{\tiny A})=β(y_{\tiny B} - y_{\tiny A})+γ(y_{\tiny C} - y_{\tiny A})\cdots\cdots\cdot⑤ \end{cases}{(x−xA)=β(xB−xA)+γ(xC−xA)⋯⋯④(y−yA)=β(yB−yA)+γ(yC−yA)⋯⋯⋅⑤
④×(yC−yA),⑤×(xC−xA)④\times(y_{\tiny C} - y_{\tiny A}),⑤\times(x_{\tiny C} - x_{\tiny A})④×(yC−yA),⑤×(xC−xA)得:
(x−xA)(yC−yA)=β(xB−xA)(yC−yA)+γ(xC−xA)(yC−yA)⋯⋯⑥(y−yA)(xC−xA)=β(yB−yA)(xC−xA)+γ(yC−yA)(xC−xA)⋯⋯⑦(x- x_{\tiny A})(y_{\tiny C} - y_{\tiny A}) = β(x_{\tiny B} - x_{\tiny A})(y_{\tiny C} - y_{\tiny A})+\cancel{γ(x_{\tiny C} - x_{\tiny A})(y_{\tiny C} - y_{\tiny A})} \cdots\cdots⑥\\ (y- y_{\tiny A})(x_{\tiny C} - x_{\tiny A}) = β(y_{\tiny B} - y_{\tiny A})(x_{\tiny C} - x_{\tiny A})+\cancel{γ(y_{\tiny C} - y_{\tiny A})(x_{\tiny C} - x_{\tiny A})}\cdots\cdots⑦ (x−xA)(yC−yA)=β(xB−xA)(yC−yA)+γ(xC−xA)(yC−yA)⋯⋯⑥(y−yA)(xC−xA)=β(yB−yA)(xC−xA)+γ(yC−yA)(xC−xA)⋯⋯⑦
⑦−⑥⑦-⑥⑦−⑥得到β,同理可得γ
Step 3
最终α、β、γα、β、γα、β、γ表达式
β=(y−yA)(xC−xA)−(x−xA)(yC−yA)(yB−yA)(xC−xA)−(xB−xA)(yC−yA)γ=(y−yA)(xB−xA)−(x−xA)(yB−yA)(yC−yA)(xB−xA)−(xC−xA)(yB−yA)α=1−β−γ\color{red}\large β=\frac{ (y- y_{\tiny A})(x_{\tiny C} - x_{\tiny A})-(x - x_{\tiny A})(y_{\tiny C} - y_{\tiny A}) }{(y_{\tiny B} - y_{\tiny A})(x_{\tiny C} - x_{\tiny A})-(x_{\tiny B} - x_{\tiny A})(y_{\tiny C} - y_{\tiny A})}\\ \: \\ \large γ=\frac{ (y- y_{\tiny A})(x_{\tiny B} - x_{\tiny A})-(x - x_{\tiny A})(y_{\tiny B} - y_{\tiny A}) }{(y_{\tiny C} - y_{\tiny A})(x_{\tiny B} - x_{\tiny A})-(x_{\tiny C} - x_{\tiny A})(y_{\tiny B} - y_{\tiny A})}\\ \: \\ α=1-β-γ\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:β=(yB−yA)(xC−xA)−(xB−xA)(yC−yA)(y−yA)(xC−xA)−(x−xA)(yC−yA)γ=(yC−yA)(xB−xA)−(xC−xA)(yB−yA)(y−yA)(xB−xA)−(x−xA)(yB−yA)α=1−β−γ
到此,重心坐标的插值就算结束了,单独在二维平面或者三维平面根据四个点的坐标算出重心坐标(权重)然后插值P的法线、uv坐标等等一切信息,都可得到非常正确的结果了
但是,投影后的插值就很有讲究了
透视投影的基础知识,这里就不再赘述了,其相关详细步骤,可看 这篇文章的4.3部分
对于空间中一个特定的三角形而言,只有三个顶点携带了坐标信息(x,y,z)(x,y,z)(x,y,z),对其做透视投影操作,这三个点变到了裁剪空间,此时,如果我们想要得到一张深度图的做法是什么?
建立深度缓存的方法
- 先建立一个深度缓存,其实就是个二维数组zbuffer[width][height],并且初始化每个数组元素为无穷
- 遍历每个三角形所覆盖的每个像素,
将该像素所对应的场景中的那个点的z值
跟zbuffer对应位置的z作比较,小则覆盖
问题就是怎么知道该像素的z
是多少?
(1) 你可能会想到,我们已经知道投影变换后的三个顶点在屏幕上的坐标(xA,yA),(xB,yB),(xC,yC)\large(x_{\tiny A},y_{\tiny A}),(x_{\tiny B},y_{\tiny B}),(x_{\tiny C},y_{\tiny C})(xA,yA),(xB,yB),(xC,yC)和目标像素P(x,y)(x,y)(x,y)。算出P点的重心坐标,然后我有已知三个顶点的深度Z,插值即可。想法很美好,但这样的做法是错的
,不能用插值后算出的(α,β,γ)(α,β,γ)(α,β,γ)直接插值的原因很多,部分原因如下:
投影后三角形的形状一般情况下会发生变化。空间中一个正三角形,投影后可能变成一个特别窄的三角形,这时候我算出来的该像素的权重比(重心坐标)肯定跟空间中该像素对应的点在三角形内的权重比不同,所以直接插值,不可取。
投影后,视椎体远/近平面的点,经过Squish变换后,z值是不变的,但是位于视椎体中间的点,变换后z的绝对值会变大,因此在投影后的三角形上直接插值,不可取
(2)可能还会想到,对屏幕空间的目标像素P点应用透视投影矩阵的逆
,做个逆变换变回原来的空间中,那就知道P点在空间中的准确位置了,然后再插值深度,再写回深度缓存中P像素位置中。 OK这样做很准确,但是,每个像素都要做一次逆矩阵运算,我深度图的分辨率可能几百万个像素,这计算量不能接受
啰里巴嗦一大堆,希望我表达得没有问题,有些问题脑子里清楚,但是说出来就不知道怎么说。如果有错也请大家多多指教
3 透视投影插值矫正
3.1 透视矫正后的深度插值公式
国际惯例,先说结论,如果对推导没兴趣的直接套公式即可
1Z=α′1ZA+β′1ZB+γ′1ZC\displaystyle\large\color{red} \frac{1}{Z}=α'\frac{1}{Z_A}+β'\frac{1}{Z_B}+γ'\frac{1}{Z_C}Z1=α′ZA1+β′ZB1+γ′ZC1
符号说明:带 ′'′ 的都是投影后的值,不带的是投影前的值
Z:屏幕空间的点P所对应的光差空间的点的深度值,我们求解的目标值α′、β′、γ′:屏幕空间上算出来的重心坐标(权重)ZA、ZB、ZC:空间中ABC三个顶点的深度值Z:屏幕空间的点P所对应的光差空间的点的深度值,我们求解的目标值 \\α'、β'、γ':屏幕空间上算出来的重心坐标(权重) \\Z_A、Z_B、Z_C:空间中ABC三个顶点的深度值Z:屏幕空间的点P所对应的光差空间的点的深度值,我们求解的目标值α′、β′、γ′:屏幕空间上算出来的重心坐标(权重)ZA、ZB、ZC:空间中ABC三个顶点的深度值
推导过程核心思想
:通过投影后的三角形内点P′P'P′的α′、β′、γ′α'、β'、γ'α′、β′、γ′,计算出投影前三角形内点PPP的深度值
Step 1:找到投影前后的重心坐标的关系
对公式1=α′+β′+γ′1=α'+β'+γ'1=α′+β′+γ′做恒等变形
ZZ=ZAZAα′+ZBZBβ′+ZCZCγ′\frac{Z}{Z}=\frac{Z_A}{Z_A}α'+\frac{Z_B}{Z_B}β'+\frac{Z_C}{Z_C}γ'ZZ=ZAZAα′+ZBZBβ′+ZCZCγ′
左右同×Z
Z=(ZZAα′)ZA+(ZZBβ′)ZB+(ZZCγ′)ZC………①Z =(\frac{Z}{Z_A}α')Z_A+(\frac{Z}{Z_B}β')Z_B+(\frac{Z}{Z_C}γ')Z_C\dots\dots\dots①Z=(ZAZα′)ZA+(ZBZβ′)ZB+(ZCZγ′)ZC………①
对比投影前的插值公式
Z=αZA+βZB+γZC⋯⋯⋯⋯②Z = αZ_A+βZ_B+γZ_C\cdots\cdots\cdots\cdots②Z=αZA+βZB+γZC⋯⋯⋯⋯②
联立①②,得
α=ZZAα′,β=ZZBβ′,γ=ZZCγ′α=\frac{Z}{Z_A}α',β=\frac{Z}{Z_B}β',γ=\frac{Z}{Z_C}γ'α=ZAZα′,β=ZBZβ′,γ=ZCZγ′
Step 2:得到透视修正后深度插值公式
因为1=α+β+γ1=α+β+γ1=α+β+γ,且α=ZZAα′,β=ZZBβ′,γ=ZZCγ′\displaystyle α=\frac{Z}{Z_A}α',β=\frac{Z}{Z_B}β',γ=\frac{Z}{Z_C}γ'α=ZAZα′,β=ZBZβ′,γ=ZCZγ′
所以
1=ZZAα′+ZZBβ′+ZZCγ′⋯⋯⋯③1 = \frac{Z}{Z_A}α'+\frac{Z}{Z_B}β'+\frac{Z}{Z_C}γ'\cdots\cdots\cdots③1=ZAZα′+ZBZβ′+ZCZγ′⋯⋯⋯③
对③左右同×1Z\times \frac{1}{Z}×Z1
1Z=α′1ZA+β′1ZB+γ′1ZC\displaystyle\color{red}\Large\frac{1}{Z}=α' \frac{1}{Z_A}+β'\frac{1}{Z_B}+γ'\frac{1}{Z_C}Z1=α′ZA1+β′ZB1+γ′ZC1
到此已经能很好的生成一张深度缓存、shadow map了
3.2 一个非常重要的透视投影的细节
注意在完成透视投影后,在屏幕空间上的三个顶点A′B′C′A'B'C'A′B′C′的zzz分量ZA,ZB,ZCZ_A,Z_B,Z_CZA,ZB,ZC存放的并不是原本位于观察空间中的三个顶点的正确深度,应用投影矩阵后这个z分量存放的深度已经变远了
,而原本的Z,经过变换后,跑到的齐次坐标下的w分量上
下面我们取视椎体内部任意一点P=(x,y,z,1)P=(x,y,z,1)P=(x,y,z,1),应用透视投影矩阵
[2nr−l0l+rl−r002nt−bb+tb−t000n+fn−f−2nfn−f0010]⋅[xyz1]=[不关心懒得算不重要z]\Large \begin{bmatrix} \frac{2n}{r-l}&0&\frac{l+r}{l-r}&0 \\ 0 & \frac{2n}{t-b}&\frac{b+t}{b-t}&0 \\ 0&0&\frac{n+f}{n-f}&\frac{-2nf}{n-f}\\ 0&0&1&0 \end{bmatrix}·\begin{bmatrix}x\\y\\z\\1\end{bmatrix} = \begin{bmatrix} \small 不关心\\\small懒得算\\ \small不重要 \\ \color{red}\mathbf z \end{bmatrix}⎣⎡r−l2n0000t−b2n00l−rl+rb−tb+tn−fn+f100n−f−2nf0⎦⎤⋅⎣⎡xyz1⎦⎤=⎣⎡不关心懒得算不重要z⎦⎤
- ok,应用透视投影矩阵后,屏幕空间的三角形顶点,
vertex[0].w()
就是顶点0在透视投影之前的正确的深度值,带插值公式的时候ZAZ_AZA取这个值,不要取.z()分量
关于Squish矩阵会把点推向远处的问题也特别简单,任选一点,左乘Msquish然后判断z的变化即可
3.2 更通用的:任意属性插值公式
III 为三角形内目标点的目标属性
插值公式:I=αIA+βIB+γIC\large I = αI_A+βI_B+γI_C I=αIA+βIB+γIC
又因为
α=ZZAα′,β=ZZBβ′,γ=ZZCγ′\largeα=\frac{Z}{Z_A}α',β=\frac{Z}{Z_B}β',γ=\frac{Z}{Z_C}γ'α=ZAZα′,β=ZBZβ′,γ=ZCZγ′
因此I=α′IA+β′IB+γ′ICI = α'I_A+β'I_B+γ'I_CI=α′IA+β′IB+γ′IC又能写成
I=Z⋅(α′IAZA+β′IBZB+γ′ICZC)\large\color{red} I=Z·(α'\frac{I_A}{Z_A}+β'\frac{I_B}{Z_B}+γ'\frac{I_C}{Z_C})I=Z⋅(α′ZAIA+β′ZBIB+γ′ZCIC)
I:I:I: 屏幕空间三角形内部点的目标属性(颜色、法线、纹理坐标等)
IA、IB、ICI_A、I_B、I_CIA、IB、IC:三个顶点的对应属性
ZA、ZB、ZCZ_A、Z_B、Z_CZA、ZB、ZC:三个顶点的观察空间的Z值(投影前的)
以下是GAMES101作业中的部分代码,以此作为案例分析如何插值任意属性
//这里计算得到重心坐标
auto [alpha, beta, gamma] = computeBarycentric2D(i+0.5, j+0.5, t.v);// w_reciprocal就是该像素p对应投影前的深度值z
float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());// 但是这里又用了任意属性插值公式, 并且IA取的v[0].z()
float z_interpolated = w_reciprocal*(alpha*v[0].z()/v[0].w() + beta*v[1].z()/v[1].w() + gamma*v[2].z()/v[2].w());
w_reciprocal=1α′1ZA+β′1ZB+γ′1ZC\displaystyle\large w\_reciprocal=\frac{1}{α' \frac{1}{Z_A}+β'\frac{1}{Z_B}+γ'\frac{1}{Z_C}}w_reciprocal=α′ZA1+β′ZB1+γ′ZC11
\quad\quad w_reciprocal就是 1w\large \frac{1}{w}w1,w就是投影前的深度值Z。计算出来的Z作为下面的Z,去计算任意属性
z_interpolated=Z⋅(α′IAZA+β′IBZB+γ′ICZC)\displaystyle\large z\_interpolated =\color{red}Z\color{normal} ·(α'\frac{I_A}{Z_A}+β'\frac{I_B}{Z_B}+γ'\frac{I_C}{Z_C})z_interpolated=Z⋅(α′ZAIA+β′ZBIB+γ′ZCIC)
\quad\quad OK任意属性就是的深度值。也可以取别的属性。
通过上面可以总结,插值任意属性的过程分两步:
- (1)插值zzz,因为插值任意属性的公式里必须用到z
- (2)插值任意属性III。IA、IB、ICI_A、I_B、I_CIA、IB、IC的选取方法是屏幕空间的三个顶点所包含的信息(如上面的AZ用到的就真的是V[0].z()),
不管投影后有没有变,直接带入,应该就是这个公式的价值。目前我能想到的是这样,留个坑以后确定了再填
可以看到,上面很多都是不太严谨的基于案例的个人猜测,但是应该对跟我一样的对此过程不太熟悉的朋友们有一些些帮助,具体的更严谨的推导,建议搜索别的文章进行学习
【重心坐标插值、透视矫正插值】原理以及用法见解(GAMES101深度测试部分讨论)相关推荐
- 6、计算机图形学——着色频率、插值与插值的矫正
一.着色频率 通过光照模型可知,最终的光照结果和光照点的法线向量关系很大.所以,根据不同的法线向量,就有不同的着色方法.在图形学中,法线分为:面法线.顶点法线和像素法线.光照和这三种法线相互作用,就有 ...
- 图形学基础之透视校正插值
透视校正插值 (Perspective-Correct Interpolation) 问题的提出 在使用光栅化的图形学方法中,法线,颜色,纹理坐标这些属性通常是绑定在图元的顶点上的.在3D空间中,这些 ...
- 数学建模十大算法02—插值与拟合(拉格朗日插值、三次样条插值、线性最小二乘法……)
文章目录 引入 一.插值 1.1 分段线性插值 1.2 牛顿插值法 1.3 拉格朗日插值多项式 1.4 样条插值 1.4.1 三次样条插值 1.5 二维插值 1.5.1 插值节点为网格节点 1.5.2 ...
- 线性插值插值_揭秘插值搜索
线性插值插值 搜索算法指南 (Searching Algorithm Guide) Prior to this article, I have written about Binary Search. ...
- Matlab实现线性插值、抛物插值、牛顿插值、拉格朗日插值、分段抛物插值、分段线性插值
目录 线性插值 原理 流程图 代码 抛物插值 原理 流程图 代码 拉格朗日插值 代码 牛顿插值 原理 代码 分段线性插值 代码 线性插值 原理 流程图 单个点的线性插值代码 X=[0.2 0.4]; ...
- 清风数学建模学习笔记——应用matlab实现分段三次埃尔米特(Hermite)插值与三次样条插值
插值算法 数模比赛中,常常需要根据已知的函数点进行数据.模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,模拟产生一些新的但又比较靠谱的值来满足需求 ...
- mysql 实时聚合分析,mysql累积聚合原理与用法实例分析
本文实例讲述了mysql累积聚合原理与用法.分享给大家供大家参考,具体如下: 累积聚合为聚合从序列内第一个元素到当前元素的数据,如为每个员工返回每月开始到现在累积的订单数量和平均订单数量 行号问题有两 ...
- python装饰器原理-Python装饰器原理与用法分析
这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念.原理.使用方法及相关操作注意事项,需要的朋友可以参考下 本文实例讲述了Python装饰器原理与用法.分享给大 ...
- python的编程模式-Python设计模式之状态模式原理与用法详解
本文实例讲述了Python设计模式之状态模式原理与用法.分享给大家供大家参考,具体如下: 状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ...
最新文章
- openstack——horizon篇
- What's the best way to get rid of get parameters from url string?
- 论文浅尝 | 融入知识的弱监督预训练语言模型
- Android中如何实现多个框,在android中的对话框中设置多个文本框
- Token九重天——如何设计区块链项目的通证模型
- Mac上的MySQL可视化工具总结
- 计算机专业直接工作简历,计算机专业个人简历工作经验怎么写
- 室内空气流动原理图_空气流动基本原理
- 消费者生产者问题,哲学家问题
- mysql jdbc dao_MYSQL 之 JDBC(九):增删改查(七)DAO的补充和重构
- 分布式算法-Paxos
- OSI 七层模型和TCP/IP模型及对应协议
- 根据accept-language 设置国际化
- Oracle中CHR()函数使用
- Flexsim常见问题记录
- html异步加载图片,javascript-img异步加载图片
- 在项目中用了Arrays.asList、ArrayList的subList,被老大公开批评
- 关于ansys阶跃载荷与斜坡载荷
- 手把手教你如何玩转Java基础面试题
- Ajax数据类型转化
热门文章
- 哥德巴赫猜想在指定区间的证明python
- HTML隐藏属性的使用(前端标签)
- 初升高零基础学哪种计算机编程好,一位家长的痛苦领悟:高考完才知道,初中有多重要!...
- 狂暴者 pat basic 练习三十 完美数列 测试点4超时,测试点五错误解决方法
- 8.物体的几何表示——隐式曲面+物体的CSG树
- 【数理题】3,0,7,19,76 找规律
- 《机器学习实战》:通俗理解支持向量机
- [BZOJ]4668: 冷战
- 微信绑定银行这3点要注意,否则一不小心钱就没了,赶紧看看
- Linux 学习笔记(自己整理仅供自己复习)