版权声明:所有的博客都是个人笔记,交流可以留言或者加QQ:2630492017 https://blog.csdn.net/qq_35976351/article/details/84871397
齐次坐标系
齐次坐标系是为了区分空间点和向量的。三维空间中,
(x,y,z)可以表示一个点
p的位置,但是也可以表示一个向量
v。对于点的移动是有实际意义的,但是移动向量没有任何意义!点和向量在三维空间中的真正区别在于是否支持移动。
引入齐次坐标
(x,y,z,w)T,
w=1表示空间的点,
w=0表示空间的向量。这样是为了后期矩阵变换的时候,统一运算规则,不用单独区分点或者向量。
空间变换矩阵
一般来说,在图形学中,使用矩阵的方式进行变换,可以把多个连续的操作压缩到一个中,减少计算量;同时利用矩阵的优化算法,可以提高计算效率。
位移矩阵:
Offset=⎣⎢⎢⎡100001000010TxTyTz1⎦⎥⎥⎤
Tx、
Ty和
Tz分别表示沿着
x、
y和
z轴的平移距离。根据矩阵的运算法则,如果是点的坐标,那么
w=1正好线性累加上位移;如果是向量,
w=0会抵消位移的效果。
绕
x轴的旋转矩阵:
RotationX=⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤
这是右手系的变换矩阵,
θ是从
x轴负向看向正向顺时针的旋转角度。
绕
y轴的旋转矩阵:
RotationY=⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤
这是右手系的变换矩阵,
θ是从
y轴负向看向正向顺时针的旋转角度。
绕
z轴的旋转矩阵:
RotationY=⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000000001⎦⎥⎥⎤
这是右手系的变换矩阵,
θ是从
z轴负向看向正向顺时针的旋转角度。
绕任意轴的旋转矩阵:
假设一个轴的向量
R=(Rx,Ry,Rz),现在绕这个轴进行旋转,那么变换矩阵应该是:
RotationY=⎣⎢⎢⎡cosθ+Rx2(1−cosθ)RyRx(1−cosθ+Rzsinθ)RzRx(1−cosθ−Rzsinθ)0RxRy(1−cosθ−Rzsinθ)cosθ+Ry2(1−cosθ)RzRy(1−cosθ+Rxsinθ)0RxRz(1−cosθ+Rysinθ)RyRz(1−cosθ−Rxsinθ)cosθ+Rz2(1−cosθ)00011⎦⎥⎥⎤
一般的建模方法
矩阵乘法是不可逆的,因此不能直接随便交换变换的顺序。先旋转再平移和先平移再旋转的效果是不同的;同样的,绕不同的轴旋转的次序不同,得到的结果可能也是不同的。一般来说,应该先执行局部的旋转,再执行局部坐标系的平移。
建模时,应该以物体为参考中心,选定一个物体的局部坐标中心
localCenter,使用齐次坐标系表示,然后再给出物体各个定点在局部坐标系中的位置,局部坐标累计上局部旋转在累计上局部中心的坐标,即可生成全局的坐标。
注意,一定是先进行局部坐标系的旋转,再执行平移;否则结果错误。还有,这里使用的列向量的机制,矩阵乘法是从右向左结合的,那么变换矩阵是:
worldPos=Offset∗Rotation∗localPos
Github示例代码,纯C++实现的渲染管线:
https://github.com/StudentErick/PipeLine