如何在GLM中对非方阵执行平移、旋转与缩放操作?
报错原因
GLM 内置的glm::translate、glm::rotate、glm::scale这类变换函数,原生只支持齐次方阵作为输入(2D变换对应3阶方阵、3D变换对应4阶方阵),没有为glm::mat3x2这类非方阵提供重载,所以会触发匹配失败的报错。
glm::mat3x2本质是2D仿射变换的紧凑存储格式:对应3阶齐次变换矩阵省略了最后一行(2D仿射变换的齐次矩阵最后一行固定为[0, 0, 1],不需要额外存储)。
非方阵变换实现方案
通用逻辑是先把非方阵升维为对应维度的齐次方阵,调用GLM内置变换函数完成操作后,再截取回目标非方阵格式即可,三类变换的实现示例如下:
1. 平移操作
#include <glm/glm.hpp> #include <glm/gtx/transform.hpp> glm::mat3x2 transform_mat = /* 你的原始mat3x2矩阵 */; glm::vec2 offset = glm::vec2(20.f, 15.f); // 平移偏移量 // 升维为3阶齐次方阵 glm::mat3 homo_mat = glm::mat3(transform_mat); // 调用GLM内置平移函数 homo_mat = glm::translate(homo_mat, offset); // 截取回mat3x2格式 transform_mat = glm::mat3x2(homo_mat);
也可以直接修改mat3x2的第三列(平移分量)实现更高效的操作:
transform_mat[2] += offset;
2. 旋转操作
float rotate_rad = glm::radians(30.f); // 旋转角度,单位弧度 glm::mat3 homo_mat = glm::mat3(transform_mat); homo_mat = glm::rotate(homo_mat, rotate_rad); transform_mat = glm::mat3x2(homo_mat);
3. 缩放操作
glm::vec2 scale_factor = glm::vec2(0.5f, 2.f); // 缩放系数 // 方法1:齐次矩阵中转,适配所有场景 glm::mat3 homo_mat = glm::mat3(transform_mat); homo_mat = glm::scale(homo_mat, scale_factor); transform_mat = glm::mat3x2(homo_mat); // 方法2:直接修改基向量,性能更高 transform_mat[0] *= scale_factor.x; transform_mat[1] *= scale_factor.y;
通用扩展逻辑
其他维度的非方阵变换都可以用同样的逻辑实现:比如3D场景下的mat4x3紧凑存储格式,只需要升维为4阶齐次方阵操作后再截取即可。
内容的提问来源于stack exchange,提问作者Paiku Han
相关产品推荐
相关产品推荐

