如何操作物体在3D空间中的位置呢,方法有很多。
这里总结一下最流行的矩阵操作。
1. 放大缩小一个物体,我们可以填写一个放大缩小矩阵,如下代码:
void InitScaleTransform(Matrix4f& m) const { m.m[0][0] = m_scale.x; m.m[0][1] = 0.0f ; m.m[0][2] = 0.0f ; m.m[0][3] = 0.0f; m.m[1][0] = 0.0f ; m.m[1][1] = m_scale.y; m.m[1][2] = 0.0f ; m.m[1][3] = 0.0f; m.m[2][0] = 0.0f ; m.m[2][1] = 0.0f ; m.m[2][2] = m_scale.z; m.m[2][3] = 0.0f; m.m[3][0] = 0.0f ; m.m[3][1] = 0.0f ; m.m[3][2] = 0.0f ; m.m[3][3] = 1.0f; }
这样填写了一个4X4的矩阵,就可以和物体位置相乘,达到放大或者缩小物体的目的
2. 选择物体的时候也是同理,不过矩阵不一样罢了,如下:
rx.m[0][0] = 1.0f; rx.m[0][1] = 0.0f ; rx.m[0][2] = 0.0f ; rx.m[0][3] = 0.0f; rx.m[1][0] = 0.0f; rx.m[1][1] = cosf(x); rx.m[1][2] = -sinf(x); rx.m[1][3] = 0.0f; rx.m[2][0] = 0.0f; rx.m[2][1] = sinf(x); rx.m[2][2] = cosf(x) ; rx.m[2][3] = 0.0f; rx.m[3][0] = 0.0f; rx.m[3][1] = 0.0f ; rx.m[3][2] = 0.0f ; rx.m[3][3] = 1.0f;
其中选择矩阵就是{{cosf(x), -sinf(x)},{sinf(x), cosf(x)}},这个是需要熟记的矩阵,如下图:
其中空出x行,是表示绕x轴选择。如需要绕y轴或者z轴,可以填写如下代码:
ry.m[0][0] = cosf(y); ry.m[0][1] = 0.0f; ry.m[0][2] = -sinf(y); ry.m[0][3] = 0.0f; ry.m[1][0] = 0.0f ; ry.m[1][1] = 1.0f; ry.m[1][2] = 0.0f ; ry.m[1][3] = 0.0f; ry.m[2][0] = sinf(y); ry.m[2][1] = 0.0f; ry.m[2][2] = cosf(y) ; ry.m[2][3] = 0.0f; ry.m[3][0] = 0.0f ; ry.m[3][1] = 0.0f; ry.m[3][2] = 0.0f ; ry.m[3][3] = 1.0f; rz.m[0][0] = cosf(z); rz.m[0][1] = -sinf(z); rz.m[0][2] = 0.0f; rz.m[0][3] = 0.0f; rz.m[1][0] = sinf(z); rz.m[1][1] = cosf(z) ; rz.m[1][2] = 0.0f; rz.m[1][3] = 0.0f; rz.m[2][0] = 0.0f ; rz.m[2][1] = 0.0f ; rz.m[2][2] = 1.0f; rz.m[2][3] = 0.0f; rz.m[3][0] = 0.0f ; rz.m[3][1] = 0.0f ; rz.m[3][2] = 0.0f; rz.m[3][3] = 1.0f;
注意下就是C++的sinf和cosf函数都是以弧度为单位的,所以需要知道弧度和度的转换:
#define M_PI 3.1415926 #define ToRadian(x) (float)(((x) * M_PI / 180.0f)) #define ToDegree(x) (float)(((x) * 180.0f / M_PI))
设置好绕三个轴选择的矩阵之后,可以合并起来,三个矩阵相乘,就得到任意角度选择了:
m = rz * ry * rx;
3. 设置位移的矩阵就简单点:
m.m[0][0] = 1.0f; m.m[0][1] = 0.0f; m.m[0][2] = 0.0f; m.m[0][3] = m_worldPos.x; m.m[1][0] = 0.0f; m.m[1][1] = 1.0f; m.m[1][2] = 0.0f; m.m[1][3] = m_worldPos.y; m.m[2][0] = 0.0f; m.m[2][1] = 0.0f; m.m[2][2] = 1.0f; m.m[2][3] = m_worldPos.z; m.m[3][0] = 0.0f; m.m[3][1] = 0.0f; m.m[3][2] = 0.0f; m.m[3][3] = 1.0f;
三个矩阵都设置好之后,同理相乘之后就得到任意缩放,选择角度和位移的3D物体了。
学3D的人,也许需要培养空间想象力,这里要用好我们的想象:
要想象成每次都是从原点出发,设置好大小,选择,然后直接放到需要的位置,而不是从上一次的位置出发。相当于从model space转换到world space。
刚学图像学的人也许会觉得这样的转换会浪费计算时间,不过其实这样的转换时间效率可以说是O(1),所以不消耗什么时间。
3D Transformation 3D物体位移函数
时间: 2024-12-18 18:40:24