three.js+WebGL踩坑经验合集(6.1):负缩放,负定矩阵和行列式的关系(2D版本)

春节忙完一轮,总算可以继续来写博客了。希望在春节假期结束之前能多更新几篇。

这一篇会偏理论多一点。笔者本没打算在这一系列里面重点讲理论,所以像相机矩阵推导这种网上已经很多优质文章的内容,笔者就一笔带过。

然而关于负缩放,笔者未能找到从正负缩放到行列式正负的完整推导过程(可能是笔者没用对关键词吧,GPT也还没去用),中途也就找到了一个正/负定矩阵的概念。该说法已经有点正负缩放的意思了,所以本篇虽然侧重理论,但也会结合第5篇的坑进行阐述。

回顾第5篇

(5.2):THREE.Mesh和THREE.Line2在镜像处理上的区别

笔者在排查Line2镜像丢失的bug时,发现了three.js处理正反面的逻辑,它对接原生WebGL的正反面定义——三角面3个点的绕序(顺逆时针)。

three.js的实现机制是,如果物体的变换矩阵的秩(行列式)为负数,则指示物体做了带有负缩放矩阵的变换,就把逆时针旋转的三角面从背面改为正面。

从这一过程可以发现,对一个三角面应用负缩放时,其三个点的绕序会发生变化,而正缩放则不会。而一个缩放的正负,three.js是通过矩阵的秩进行判断的。

这里笔者再多嘴一下,如果矩阵的秩等于0,那么它就会把三角面的三个点变换到在同一直线上,或者会让两个或者3个点完全重合。笔者姑且称之为零定矩阵。与此同时,它也是个不可逆的矩阵。

本篇我们先拿2D的3*3矩阵来探讨行列式的正负对三点绕序的影响。3D的情况比较复杂,因为它涉及到不同轴的情况,笔者有很长一段时间以为3D无法定义负矩阵,直到研读了three.js的代码才恍然大悟。

推导过程有点繁琐,此处先给结论:矩阵缩放的正负,正负定矩阵,行列式的正负性这3者完全等价,正定矩阵不改变绕序,负定矩阵改变,零定矩阵是不可逆矩阵,它会让不共线的点变成共线甚至重合。

好,下面进入正题。

给定2D上的3个不共线的点O(x0, y0),A(x1,y1),B(x2,y2),要判断这3个点的绕序,可以作向量OA,OB,然后通过计算这两个2D向量的叉乘值得出。如下图所示,OA旋转到OB是顺时针。

对这3个点应用正定矩阵,对应两向量的叉乘结果不变,而应用负定矩阵,则叉乘结果改变,如下图所示。

然后我们给定一个3*3的2D变换矩阵(不管是2D点还是3D点,矩阵的阶数都比点的维数多1,目的是加法和乘法合并,前面讲过比较多次了,此处不再重复,实在不懂可以问我)。

对一个2D点应用矩阵,运算过程如下:

可见通过给点的最后一行补1,最后一列就实现了加法。

由于此处只研究2D点的绕序问题,因此最后一行的结果我们无需关注,在此场景它只为了让矩阵乘法计算可以正常进行。

下面我们的推导过程将分以下几步:

1 计算OA,OB向量及它们的叉乘值c

2 计算点O,A,B应用矩阵后的结果O',A',B'

3 计算向量O'A',O'B'以及它们的叉乘值c'

4 考察c和c'符号的一致性,并给出一致性跟矩阵元素的关系

5 上述关系对应到行列式上验证上面给出的结论

OA和OB是(x1-x0,y1-y0),以及(x2-x0, y2-y0),为了书写简便,后面会把x1-x0记为Δx1,y1-y0记为Δy1,其它类似。

两向量(x1,y1),(x2,y2)的2D叉乘公式为x1*y2-x2*y1,所以OA和OB的叉乘结果为

至此,第一步计算完成。

第二步,计算矩阵变换后的O,A,B,如上所述,其结果为

第三步,计算O'A',O'B'和他们俩的叉乘值

类似地有

然后叉乘值为

这个推导过程可能会让对数学不敏感的小伙伴们感到蛋疼,所以笔者曾经考虑过要不要牺牲一定的严谨性,拿个特殊点,简单点的变量来做演示。如果实在看不下去,小伙伴们可以让O=(0,0),A=(1,0),B=(0,1)来演算一遍,找下感觉。对于2D来说,拿特殊点是没有任何毛病的,除非你拿了重合的点或者共线的3点。

我们对照下OA和OB的叉乘,以及O'A'和O'B的叉乘,后者等于前者乘以(m11m22-m22*m11), 因此判断向量变换前叉积符号的一致性,只需要判断m11m22-m22*m11的符号即可。可见,矩阵对不共线3点绕序的影响仅跟矩阵的4个元素有关,而跟你的取点无关。

现在我们把刚才说到的矩阵搬过来,看看它跟行列式的关系。

发现计算结果只取了3*3矩阵中的前面两阶的元素做了一个行列式的计算。而第三列中的元素,因为它只管平移,并且跟点坐标无关,所以它在计算向量的时候就已经被消去了。至于第三行,因为它是为了将加法和乘法合并,不是本文的关注点,所以全程我们都没有让它参与到计算当中。

然而three.js自带的Matrix3类,它的行列式值则是严格按照数学的定义,按3阶行列式来书写:

那为什么我们在使用的过程中没有出现任何问题呢?我们把刚才3*3矩阵乘以点的计算公式拿过来。

为了让点变换的过程中,为合并而补充的那个1保持不变,我们应该让第三行的计算结果

m31*x+m32*y+m33恒等于1,因此结果不能受x和y影响,所以m31和m32要等于0,而剩下的m33,自然就等于1了。也就是说,这一行填充的是单位矩阵的数值。

熟悉行列式运算法则的小伙伴应该一眼就看得出来,用到第三列元素的项都要跟0相乘,否则就是跟1相乘。但为了照顾更多的小伙伴,笔者也按3阶行列式的定义演算一遍。

可见,用单位矩阵填充第3行以后,其行列式的值跟2阶行列式出来的结果完全一致,证毕。

这里需要注意的一点是,three.js的Matrix3允许第三行不使用单位矩阵的数值。这时候,它的行列式符号不能在2D变换的场景下判断矩阵的正负性。

推导完成了,来小结一下(注意以下结论均建立在Matrix3做2D变换的场景):

1 正负缩放矩阵,正负定矩阵,行列式正负完全等价(此外还有零的情况)

2 正负矩阵的性质:不共线的3个2D点,正矩阵不会修改它们的绕序,负矩阵会

3 three.js利用这一性质,根据WebGL正反面的规则修复单面材质镜像后不能正确显示的问题

4 零矩阵会使它们共线或者共点,且不可逆

5 判断一个矩阵的正负,用的是3*3矩阵前两行两列所构成的行列式的符号。若想对齐到3阶矩阵,则第三行必须按照单位矩阵进行填充,否则会出现错误的结果

现在我们来简单聊聊3D,为什么前面说3D比2D复杂。

大家脑补一下,我们给2D点直接加上z坐标,全部设置为0。如果我们应用x方向负缩放或者y方向负缩放的话,那么应用前面的结论一点毛病都没有,但若应用z负缩放,则所有的点都不会有任何变化,哪怕你不设置为0,只要z值完全一样,那翻转后,也就是z值统一改成一样的数字,但这时候,其实正反面已经颠倒了。

就这么一个简单的情况,本文的结论就已经无法应用到3D上了,所以今天我们就先到这里,后面我会跟大家继续探讨3D矩阵的正负缩放问题,敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962347.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Baklib解析内容中台与人工智能技术带来的价值与机遇

内容概要 在数字化转型的浪潮中,内容中台与人工智能技术的结合为企业提供了前所未有的发展机遇。内容中台作为一种新的内容管理和生产模式,通过统一管理和协调各种内容资源,帮助企业更高效地整合内外部数据。而人工智能技术则以其强大的数据…

Learning Vue 读书笔记 Chapter 4

4.1 Vue中的嵌套组件和数据流 我们将嵌套的组件称为子组件,而包含它们的组件则称为它们的父组件。 父组件可以通过 props向子组件传递数据,而子组件则可以通过自定义事件(emits)向父组件发送事件。 4.1.1 使用Props向子组件传递…

小程序电商运营内容真实性增强策略及开源链动2+1模式AI智能名片S2B2C商城系统源码的应用探索

摘要:随着互联网技术的不断发展,小程序电商已成为现代商业的重要组成部分。然而,如何在竞争激烈的市场中增强小程序内容的真实性,提高用户信任度,成为电商运营者面临的一大挑战。本文首先探讨了通过图片、视频等方式增…

【游戏设计原理】96 - 成就感

成就感是玩家体验的核心,它来自完成一件让自己满意的任务,而这种任务通常需要一定的努力和挑战。游戏设计师的目标是通过合理设计任务,不断为玩家提供成就感,保持他们的参与热情。 ARCS行为模式(注意力、关联性、自信…

Linux系统上安装与配置 MySQL( CentOS 7 )

目录 1. 下载并安装 MySQL 官方 Yum Repository 2. 启动 MySQL 并查看运行状态 3. 找到 root 用户的初始密码 4. 修改 root 用户密码 5. 设置允许远程登录 6. 在云服务器配置 MySQL 端口 7. 关闭防火墙 8. 解决密码错误的问题 前言 在 Linux 服务器上安装并配置 MySQL …

读书笔记-《Redis设计与实现》(一)数据结构与对象(下)

各位朋友新年快乐~ 今天我们来继续学习 Redis 。 01 整数集合 当集合仅包含整数值,并且元素数量不多时,Redis 就会采用整数集合来作为集合键的底层实现。 typedef struct intset {// 编码方式uint32_t encoding;// 元素数量uint32_t length;// 数组in…

IP服务模型

1. IP数据报 IP数据报中除了包含需要传输的数据外,还包括目标终端的IP地址和发送终端的IP地址。 数据报通过网络从一台路由器跳到另一台路由器,一路从IP源地址传递到IP目标地址。每个路由器都包含一个转发表,该表告诉它在匹配到特定目标地址…

上海亚商投顾:沪指冲高回落 大金融板块全天强势 上海亚商投

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天冲高回落,深成指、创业板指午后翻绿。大金融板块全天强势,天茂集团…

数据分析系列--④RapidMiner进行关联分析(案例)

一、核心概念 1.项集(Itemset) 2.规则(Rule) 3.支持度(Support) 3.1 支持度的定义 3.2 支持度的意义 3.3 支持度的应用 3.4 支持度的示例 3.5 支持度的调整 3.6 支持度与其他指标的关系 4.置信度&#xff0…

HTB靶场Adminstrator

文章目录 靶机信息域环境初步信息收集与权限验证FTP 登录尝试SMB 枚举尝试WinRM 登录olivia域用户枚举 获取Michael权限BloodHound 提取域信息GenericAll 获取Benjamin权限ForceChangePasswordftp登录benjamin 获取Emily权限pwsafehashcat 获取Ethan权限获取管理员(Administrat…

C语言指针专题三 -- 指针数组

目录 1. 指针数组的核心原理 2. 指针数组与二维数组的区别 3. 编程实例 4. 常见陷阱与防御 5. 总结 1. 指针数组的核心原理 指针数组是一种特殊数组,其所有元素均为指针类型。每个元素存储一个内存地址,可指向不同类型的数据(通常指向同…

Spring Boot - 数据库集成06 - 集成ElasticSearch

Spring boot 集成 ElasticSearch 文章目录 Spring boot 集成 ElasticSearch一:前置工作1:项目搭建和依赖导入2:客户端连接相关构建3:实体类相关注解配置说明 二:客户端client相关操作说明1:检索流程1.1&…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构,通过 Key 可以快速查找到对应的 Value。B 树索引由根页面(Root&am…

vue之pinia组件的使用

1、搭建pinia环境 cnpm i pinia #安装pinia的组件 cnpm i nanoid #唯一id,相当于uuid cnpm install axios #网络请求组件 2、存储读取数据 存储数据 >> Count.ts文件import {defineStore} from piniaexport const useCountStore defineStore(count,{// a…

【MySQL — 数据库增删改查操作】深入解析MySQL的 Update 和 Delete 操作

1. 测试数据 mysql> select* from exam1; ----------------------------------------- | id | name | Chinese | Math | English | ----------------------------------------- | 1 | 唐三藏 | 67.0 | 98.0 | 56.0 | | 2 | 孙悟空 | 87.0 | 78.…

数据结构与算法之二叉树: LeetCode LCP 10. 二叉树任务调度 (Ts版)

二叉树任务调度 https://leetcode.cn/problems/er-cha-shu-ren-wu-diao-du/description/ 描述 任务调度优化是计算机性能优化的关键任务之一。在任务众多时,不同的调度策略可能会得到不同的总体执行时间,因此寻求一个最优的调度方案是非常有必要的 通…

JAVA 接口、抽象类的关系和用处 详细解析

接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口,可以只选择实现接口中的 部分方法(所有的方法都要有,可以一部分已经写具体,另一部分继续保留抽象),原因在于: 抽象类本身…

游戏引擎 Unity - Unity 启动(下载 Unity Editor、生成 Unity Personal Edition 许可证)

Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户注册

🧸安清h:个人主页 🎥个人专栏:【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎯项目基本介绍 🚦项…

视频多模态模型——视频版ViT

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》,2021由google 提出用于视频处理的视觉 Transformer 模型,在视频多模态领域有…