当前位置: 首页 > news >正文

如何判断模型矩阵是否做了镜像

除了旋转、平移缩放这些常见的仿射变换,可能还会有诸如镜像这类的特殊变换操作。像镜像的操作会改变原有网格体的拓扑结构,可能会导致开启背面剔除的情况下产生错误的显示效果。那么这个时候该怎么判断是否做了镜像然后把背面剔除调换为正面剔除呢?

现在假设有一个4x4的模型变换矩阵M,且在OpenGL右手系,矩阵左乘的情景下推导

1.方法1:矩阵行列式判断

1)判断思路

模型矩阵M:
M = [ m00 m01 m02 m03 ][ m10 m11 m12 m13 ][ m20 m21 m22 m23 ][ m30 m31 m32 m33 ]提取模型矩阵M的3x3旋转缩放部分矩阵MP计算行列式:
MP = [ m00 m01 m02 ][ m10 m11 m12 ][ m20 m21 m22 ]行列式 |MP|> 0:保持手性(右手系保持右手系)行列式 |MP|< 0:镜像变换(右手系变为左手系)

2)原理

模型矩阵M的3x3旋转缩放部分矩阵MP为缩放矩阵MS和旋转矩阵MR的乘积。
故矩阵MP可进一步分解为
MP=MR*MS
根据行列式计算规则有:
|MP|=|MR|*|MS|一、缩放矩阵部分
而MS矩阵一般为以下结构,sx,sy,sz为各轴的缩放比例:
MS = [ sx  0   0  ][ 0   sy  0  ][ 0   0   sz ]
故|MS|=sx*sy*sz。
由于沿某轴的镜像本质是该轴缩放因子为 - 1 的特殊缩放,因此:
若缩放因子均为正(无镜像),行列式为 +。
若有奇数个负缩放因子(即奇数次镜像),行列式为 -。
若有偶数个负缩放因子(偶次镜像,等效于无镜像的缩放),行列式为 +。
结论:缩放的行列式符号由负因子个数的奇偶性决定,奇数次镜像导致符号为负。二、旋转矩阵部分
因为旋转矩阵是正交矩阵(逆矩阵 = 转置矩阵)
其行列式恒为 +1(证明:正交矩阵满足(tranpose(MR)*MR = I)
两边取行列式得 |MR|² = 1),而旋转不改变定向,故|MR| = +))。
结论:旋转不改变行列式符号,保持定向。三、总结
若变换中包含奇数次镜像(或等效的负缩放),则总行列式为负数(因奇数个-1 相乘结果为-1)
若变换中包含偶数次镜像(或无镜像),则总行列式为 正数(因偶数个-1相乘结果为+1)。

3)代码实现

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>bool isModelMatrixMirrored(const glm::mat4& modelMatrix) {// 提取3x3旋转缩放部分计算行列式glm::mat3 upperLeft3x3 = glm::mat3(modelMatrix);float determinant = glm::determinant(upperLeft3x3);return determinant < 0.0f;
}

2.方法2:提取新坐标基叉积判断法

1)判断思路

通过检查变换后的坐标轴是否保持右手坐标系来判断

2)原理

同样提取M矩阵的前3x3得到矩阵MP原始坐标基为:i = [1, 0, 0]^T  (X轴)
j = [0, 1, 0]^T  (Y轴)  
k = [0, 0, 1]^T  (Z轴)其构成一个单位矩阵E而MP*E则可理解为对原始坐标基做了一个缩放旋转变换,
而缩放旋转变换是不会影响手性的,但是镜像会。
因此可以从MP矩阵里提取出变换后的坐标基做叉积运行判断手性以判断是否镜像

3)代码实现

bool isCoordinateSystemFlipped(const glm::mat4& modelMatrix) {// 提取变换后的坐标轴glm::vec3 transformedX = glm::normalize(glm::vec3(modelMatrix[0]));glm::vec3 transformedY = glm::normalize(glm::vec3(modelMatrix[1]));glm::vec3 transformedZ = glm::normalize(glm::vec3(modelMatrix[2]));// 检查是否保持右手坐标系glm::vec3 crossProduct = glm::cross(transformedX, transformedY);float dotProduct = glm::dot(crossProduct, transformedZ);// 在右手坐标系中,Z轴应该是X×Y的结果return dotProduct < 0.0f; // 如果为负,说明是左手系(镜像)
}

http://www.dtcms.com/a/423141.html

相关文章:

  • C语言常量和存储类别详解
  • 计算机视觉进阶教学之Mediapipe库(一)
  • 《道德经》第八章
  • 开源 C# 快速开发(十一)线程
  • 大学生网站建设策划书响应式网站用什么开发的
  • 交换机可以做网站跳转吗wordpress 目录样式
  • 第2章 三个小工具的编写(1)
  • 生态系统NPP及碳源、碳汇模拟实践技术应用
  • 【Rust GUI开发入门】编写一个本地音乐播放器(3. UI与后台线程通信)
  • P11013 「ALFR Round 4」C 粉碎 题解
  • 跨境商城网站建设公司做小程序要多少钱
  • scratch绘制帽子花 2025年6月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析
  • 特色专业建设展示网站北京seo培训
  • 网络原理-HTTP补充1
  • 做外贸相关的网站全面的vi设计公司
  • 如何构建高效 AI 智能体
  • 9.25训练赛+Codeforces1054 (Div. 3)
  • 老Java项目访问提示orcale 19c ORA-01017: 用户名/口令无效; 登录被拒绝
  • 目标检测:yolov7算法在RK3588上部署
  • Maya Python: 安装pymel
  • 全景网站开发待遇南宁logo设计公司
  • 北京工商局网站怎么做增资网易代理暴雪
  • 制造行业订单全生命周期管理数仓项目实战
  • 《深度学习入门:基于Python的理论与实现》第7章 卷积神经网络笔记
  • 网络游戏编程 - Socket 技术以及应用 - 上 -《了解游戏网络基础知识》
  • 珠海建网站的网络公司网站名称格式
  • 舆情观察类文章写作指南与新浪舆情通应用
  • C语言——深入理解函数声明定义和调用访问
  • 网站开发大约多少钱制作一个网站的步骤是什么
  • RabbitMQ (一)简单模式