DirectXMath库提供的变换函数
#include <windows.h>
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <iostream>
#include <iomanip> // 为将数字精确到小数点后两位
using namespace std;
using namespace DirectX;
using namespace DirectX::PackedVector;
ostream& XM_CALLCONV operator << (ostream& os, FXMVECTOR v)
{
XMFLOAT4 dest;
XMStoreFloat4(&dest, v);
os << "(" << dest.x << ", " << dest.y << ", " << dest.z << ", " << dest.w << ")";
return os;
}
ostream& XM_CALLCONV operator << (ostream& os, FXMMATRIX m)
{
for (int i = 0; i < 4; ++i)
{
os << setprecision(2) << XMVectorGetX(m.r[i]) << "\t";
os << XMVectorGetY(m.r[i]) << "\t";
os << setprecision(2) << XMVectorGetZ(m.r[i]) << "\t";
os << XMVectorGetW(m.r[i]);
os << endl;
}
return os;
}
int main() {
if (!XMVerifyCPUSupport())
{
cout << "directx math not supported" << endl;
return 0;
}
//(x,y,z,0) 表示向量
//(x,y,z,1) 表示点
XMVECTOR a = XMVectorSet(0.5f, 2.0f, 1.0f, 0.0f);// 例3.2里的缩放比例
XMVECTOR b3_2max = XMVectorSet(-4.0f, -4.0f, 0.0f, 1.0f); // 例3.2里的最小点坐标
XMVECTOR c = XMVectorSet(12.0f, -10.0f, 0.0f, 1.0f); // 例3.4里的移动点
XMVECTOR c3_4min = XMVectorSet(-8.0f, 2.0f, 0.0f, 1.0f); // 例3.4里的最小点坐标
float k = (-30.0 / 180 ) * XM_PI;// 例3.3里的角度改弧度
//缩放
XMMATRIX S1 = XMMatrixScaling(0.5f, 2.0f, 1.0f);// 生成沿 x 轴、y 轴和 z 轴缩放的矩阵。 例3.2里的缩放矩阵
XMMATRIX S2 = XMMatrixScalingFromVector(a);// 从 3D 向量生成缩放矩阵。
//旋转
XMMATRIX Rx = XMMatrixRotationX(k);// 生成绕 x 轴旋转的矩阵。输入绕 x 轴旋转的角度(以弧度为单位)。 在顺着面向原点的旋转轴观察时,角度是按顺时针方向测量的。
XMMATRIX Ry = XMMatrixRotationY(k);// 生成绕 y 轴旋转的矩阵。输入绕 y 轴旋转的角度(以弧度为单位)。 在顺着面向原点的旋转轴观察时,角度是按顺时针方向测量的。
XMMATRIX Rz = XMMatrixRotationZ(k);// 生成绕 z 轴旋转的矩阵。输入绕 z 轴旋转的角度(以弧度为单位)。 在顺着面向原点的旋转轴观察时,角度是按顺时针方向测量的。
XMMATRIX Rn = XMMatrixRotationAxis(XMVectorSplatOne(), k);// 生成围绕任意轴旋转的矩阵。
//平移
XMMATRIX T1 = XMMatrixTranslation(12.0f, -10.0f, 0.0f);// 从指定的偏移量生成转换矩阵。 例3.4里的平移矩阵
XMMATRIX T2 = XMMatrixTranslationFromVector(c);// 从向量生成转换矩阵。
//向量与矩阵的乘积
XMVECTOR x = XMVector3TransformCoord(c3_4min, T1);// 书上:计算向量与矩阵的乘积aA, 此函数针对点的变换,即总是默认a的w=1。 官方:按给定矩阵转换 3D 向量,将结果投影回 w = 1。
XMVECTOR y = XMVector3TransformNormal(b3_2max,S1);// 书上:计算向量与矩阵的乘积aA, 此函数针对向量的变换,即总是默认a的w=0。 官方:按给定矩阵转换 3D 矢量法线。
//对于最后的两个函数来说,用户不必显式设置w分量,因为在执行XMVector3TransformCoord时,默认w=1,而当执行XMVector3TransformNormal时,默认w=0.
cout << "例3.2中的缩放矩阵 S1 = " << endl << S1 << endl;
cout << "3D向量中的分量构建的缩放矩阵 S2 = " << endl << S2 << endl;
cout << "绕x轴“逆时针”旋转30度的矩阵 Rx = " << endl << Rx << endl;
cout << "绕y轴“逆时针”旋转30度的矩阵 Ry = " << endl << Ry << endl;
cout << "绕z轴“逆时针”旋转30度的矩阵 Rz = " << endl << Rz << endl;
cout << "绕任意轴“逆时针”旋转30度的矩阵 Rn = " << endl << Rn << endl;
cout << "例3.4里的平移矩阵 T1 = " << endl << T1 << endl;
cout << "3D向量中的分量构建的平移矩阵 T2 = " << endl << T2 << endl;
cout << "例3.4中进行平移变换后的向量 x = " << endl << x << endl;
cout << "例3.2中进行缩放变换后的向量 y = " << endl << y << endl;
}
运行结果:
个人总结笔记
1.1 线性变换 (linear transformation)
u和v是任意3D向量,k为标量。
1.1.1 缩放 (scaling)
缩放矩阵 (scaling matrix):
对应逆矩阵:
1.1.2 旋转 (rotation)
绕x轴旋转:
绕y轴旋转:
绕z轴旋转:
绕任意轴旋转:
其中,。
1.2 仿射变换 (affine transformation)
一个线性变换 + 一个平移变换
b为平移向量。
矩阵表示:
A是一个线性变换的矩阵表示。
1.2.1 齐次坐标 (homogeneous coordinate)
(x,y,z,0) 表示向量;
(x,y,z,1) 表示点。
如果用w=1把坐标扩充为齐次坐标,那么就可以将上式更简洁地写作:
1.2.2 平移 (translation)
平移矩阵 (translation matrix):
对应逆矩阵:
1.2.3 仿射变换矩阵的几何意义
刚体变换 (rigid body transformation) 本质是一种 保形 (shape preserving) 变换。
刚体变换用仿射变换来表示:
为描述物体旋转操作的旋转变换,b为定义物体平移操作的平移向量。
这种思路同样可以运用在缩放或 斜切 (skew) 变换上。
1.3 变换的复合 (composition of transformations)
C=SRT
S是缩放矩阵,R是旋转矩阵,T是平移矩阵。
1.4 坐标变换 (change of coordinate transformation)
不同标架间的坐标的转换。
//在本书上
标架 (frame) = 参考系 (frame of reference) = 空间 (space) = 坐标系 (coordinate system)
1.4.1 坐标变换的向量、点、矩阵表示
向量:
点 :
从标架 A 变换到标架 B,u、v、w分别是指向标架 A 中 x轴,y轴,z轴 正方向上的单位向量。
如果使用齐次坐标,就可以用同一公式对点和向量进行处理:
如果 w=0,此式化简为 向量 的坐标变换公式;
如果 w=1,此式化简为 点 的坐标变换公式。
矩阵形式:
其中,,
,
分别表示标架 A 中的原点和诸坐标轴相对于标架 B 的齐次坐标。
坐标变换矩阵 (change of coordinate matrix) 或 标架变换矩阵 (change of frame matrix):
标架 A 中的坐标 转换(或映射, map) 为标架 B 中坐标的 4×4 矩阵。
1.4.2 坐标变换矩阵结合律
标架:F、G、H
A:坐标从 F 转换到 G 的标架变换矩阵。
B:坐标由 G 转换至 H 的标架变换矩阵。
:标架 F 中的一个向量
求此向量相对于标架 H 的坐标 :
逐步计算:
由于满足结合律,我们可将写作:
C=AB看作将坐标从标架 F 直接变换至标架 H 的标架变换矩阵,它将变换矩阵 A 和 B 结合为一个净矩阵——思路类似于函数的复合。
这种计算方法会对性能产生影响。
1.4.3 坐标变换矩阵逆矩阵
为将坐标由标架 B 转换到标架 A 的变换矩阵。
1.5 变换矩阵与坐标变换矩阵
变换:缩放、旋转和平移。
坐标变换:令几何本身发生改变的变换。行向量:坐标变换矩阵。
几何变换:改变几何体的变换。行向量:令物体先旋转再平移的放射变换矩阵。
两者计算结果相同,差别在于解析变换的角度不同。
用坐标变换:令物体保持不变,多个坐标系之间进行转换更为直观的情景中,描述对象的参考系发生变化,物体的坐标随之改变。
几何变换法:使物体仅在一个坐标系中变换的情景中,表示物体的变换而不改变参考系。