Direct变换

来源:互联网 发布:悉尼大学回国就业 知乎 编辑:程序博客网 时间:2024/05/19 13:24

Objectives
1、理解如何用矩阵去表达线性(linear)和仿射(affine)变换。
2、学习坐标系变换,如缩放、旋转。
3、发现几个变换矩阵可以通过矩阵乘法转换成一个变换网络。
4、发现如何转换坐标系从一个坐标系到另外一个。怎么去用矩阵描述这样的坐标系变换。
5、熟悉DirectXMath库提供的函数来构造变换矩阵。

线性变换

考虑一个函数对于τ(v),若其满足以下:

τ(u+v)=τ(u)+τ(v)τ(ku)=kτ(u)

那么我们说这个函数是一个线性变换。

矩阵拓展
给定一个向量u=(x,y,z),我们可以写成这样的形式。

u=(x,y,z)=xi+yj+zk=x(1,0,0)+y(0,1,0)+z(0,0,1)

其中i,j,k为标准基向量(standard basis vectors)。
故,我们有这样的结论:
τ(u)=τ(xi+yj+zk)=xτ(i)+yτ(j)+zτ(k)

所以,我们可以写成向量-矩阵乘法的形式。
τ(u)=xτ(i)+yτ(j)+zτ(k)=uA=uτ(i)τ(j)τ(k)=[x,y,z]A11A21A31A12A22A32A13A23A33

我们可以说:矩阵A是线性变换τ的矩阵表达。

缩放
我们定义缩放像这样:

S(x,y,z)=(sxx,syy,szz)

可以很容易的看出来,S是线性的。所以我们把他写成向量-矩阵相乘的形式。
S(i)=(sx,0,0)S(j)=(0,sy,0)S(k)=(0,0,sz)S=sx000sy000sy

旋转
图片截自龙书
从上图可以推导出:

Rn(v)=cosθv+sinθ(n×v)Rn(v)=projn(v)+Rn(v)=cosθv+(1cosθ)(nv)n+sinθ(n×v)

接下来就是将其转化为线性变换矩阵模式,将单位向量代入即可。
c=cosθ,s=sinθ得出
Rn=c+(1c)x2(1c)xysz(1c)xz+sy(1c)xy+szc+(1c)y2(1c)yzsx(1c)xzsy(1c)yz+sxc+(1c)z2

可以发现旋转矩阵所有行向量的长度为1,且相互正交。
所以他的逆矩阵就等于转置矩阵。
R1n=RTn

这对于计算机的运算来说是非常效率的。

仿射变换

齐次坐标系(Homogeneous Coordinates)
因为我们对于向量只能表示方向或点,无法表达位移(translation)。换句话说,向量在进行位移时,不应该被改变。而齐次坐标系提供了一个方便的表达方式,来让我们同时表达向量和点。利用齐次坐标,我们使用4次来区分:
1、(x,y,z,0)表达向量
2、(x,y,z,1)表达点

定义和矩阵表达
一个线性变换不能表达我们所有的变换。因此,我们增加一个向量:

a(u)=τ(u)+b

如果我们增加齐次坐标w=1,我们可以写的更方便,如:
[x,y,z,1]A11A21A31bxA12A22A32byA13A23A33bz0001=[x,y,z,1]

则这个4x4的矩阵被称为仿射变换的矩阵表达形式

位移

T=100bx010by001bz0001T1=100bx010by001bz0001

仿射矩阵下的缩放和旋转
如果b=0,则仿射变换可以归纳为线性变换。
缩放和旋转的4x4仿射矩阵表达:

S=sx0000sy0000sz00001Rn=c+(1c)x2(1c)xysz(1c)xz+sy0(1c)xy+szc+(1c)y2(1c)yzsx0(1c)xzsy(1c)yz+sxc+(1c)z200001

坐标系之间的转换
对于点:
这里写图片描述

pB=xuB+yvB+zwB+QB

对于向量:
这里写图片描述
pB=xuB+yvB+zwB

那么在齐次坐标系中,我们可以将他们表达在一起:

(x,y,z,w)=xuB+yvB+zwB+wQB

如果w=0,则为向量的表达形式,否则为点。
[x,y,z,w]=[x,y,z,w]uBvBwBQB=[x,y,z,w]uxvxwxQxuyvywyQyuzvzwzQz0001=xuB+yvB+zwB+wQB


Direct Math Transformation Functions

XMMATRIX XM_CALLCONV XMMatrixScaling(float ScaleX,float ScaleY,float ScaleZ);//构造一个缩放矩阵XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(FXMVECTOR Scale); // Scaling factors (sx,sy,sz)XMMATRIX XM_CALLCONV XMMatrixRotationX(float Angle); //构造一个绕X轴旋转矩阵XMMATRIX XM_CALLCONV XMMatrixRotationAxis(FXMVECTOR Axis, float Angle);//构造一个绕Axis旋转Angle的矩阵XMMATRIX XM_CALLCONV XMMatrixTranslation(float OffsetX,float OffsetY,float OffsetZ);//构造一个平移XMMATRIX XM_CALLCONV XMMatrixTranslationFromVector(FXMVECTOR Offset);XMVECTOR XM_CALLCONV XMVector3TransformCoord(FXMVECTOR V, CXMMATRIX M); //V_w = 1;XMVECTOR XM_CALLCONV XMVector3TransformNormal(FXMVECTOR V, CXMMATRIX M);//V_w = 0;
0 0
原创粉丝点击