第五章:变换矩阵

        本文是《从0开始图形学》笔记的第五章,初步介绍变换矩阵的作用和求解方式,通过本章内容,我们将掌握模型的旋转和移动。

矩阵的初认识

        图形学自然避不开矩阵,矩阵为点坐标的变换提供了一个优雅简洁的处理方案。简单来说,使用矩阵可以对物体的坐标进行旋转和移动提供统一的计算方式。

        矩阵的乘法运算法则如下图所示,以图形学用的最多的是4x4的矩阵为例

        已知矩阵M和N,其乘积为R,则R的第m行第n列元素为M第m行和N中第n列的乘积,例如:

        上面的公式可通过以下直观的感受一下

        所以,这就必然要求矩阵M的列数和矩阵N的行数要一致,否则无法相乘!那矩阵又是如何作用于点坐标的呢?我们把点坐标中的x,y,z数值排列,并在后面补上1凑成一个4行1列的矩阵,那么使用矩阵左乘它则可以得到一个新的坐表[x1,y1,z1]!

        好吧,我已经迫不及待的想展示矩阵的魔力了

        首先,定义一个矩阵,这个矩阵的来源将在后面讲到

float matrix[16] =
{0.707107, 0, -0.707107, 131.802,0, 1, 0, 0,0.707107, 0, 0.707107, -318.198,0, 0, 0, 1
};

        然后,在读入点数据的时候将每个点用矩阵进行旋转

for (int i = 0; i < _ptNum; ++i)
{iF >> _pts[i * 3 + 0] >> _pts[i * 3 + 1] >> _pts[i * 3 + 2];// 对点坐标进行旋转MatrixMultiplyPoint(matrix, &_pts[i * 3]);
}

        其中的MatrixMultiplyPoint函数中的运算过程就是上述介绍的矩阵乘法

void MatrixMultiplyPoint(float* m, float* p)
{float x, y, z;x = m[0] * p[0] + m[1] * p[1] + m[2] * p[2] + m[3];y = m[4] * p[0] + m[5] * p[1] + m[6] * p[2] + m[7];z = m[8] * p[0] + m[9] * p[1] + m[10] * p[2] + m[11];//p[0] = x;p[1] = y;p[2] = z;
}

        效果如下图

        我们将模型如愿的进行了旋转!而这一操作仅仅用了16个数而已。

矩阵详解和求法

        现在我们已经了解了矩阵的强大,那么要如何求一个矩阵呢?

        (1)矩阵的基础拆分

        矩阵可以拆分两种常用的基本作用:围绕坐标轴旋转移动,而实现这两个基本作用的数据分别位于矩阵中的不同部分,如下图所示,红色框内为旋转作用,蓝色框内为移动作用。

        两种矩阵的特点有:

        (1)两个矩阵最后一行固定为[0 0 0 1];

        (2)单围绕坐标轴旋转作用的矩阵中蓝色框部分都为0;

        (3)单移动作用的矩阵中红色框部分固定为单位阵;

        如下图,左边为单围绕坐标轴旋转的矩阵,右边为单移动的矩阵

        只要有这两种矩阵,那么就可以通过矩阵的乘法不断地累加效果,比如,我要先移动物体,其矩阵为M1,再旋转物体,其矩阵为M2,那么这两个操作的结果为M2xM1(注意:顺序不能颠倒),由前面的讲解我们可以知道M2xM1得到的还是一个4x4的矩阵!因此,我们就可以无穷无尽的进行不断地操作,只要将每次的操作矩阵左乘上当前矩阵即可,最终还是一个4x4的矩阵!所以任何复杂的操作都可以拆成多个上述的两种基础矩阵,再进行累乘得到对应的矩阵。

        (2)基础矩阵的求法

        那么如何求解这两类基础矩阵呢?这里我们提供一个结果,不展开详细的求解。单围绕坐标轴旋转的矩阵可根据其围绕x轴,y轴,z轴分为3种,依次如下图(假设旋转角度为\alpha

        单移动矩阵更简单,假设要对一个模型在三个轴方向上移动(x, y, z),那么它的矩阵就是

        这里有一个注意点是刚接触矩阵的人很容易搞不清楚的,矩阵的所有旋转都是以坐标系原点为轴点的,如果想要模型绕着自身的某个坐标(x, y, z)旋转,则需要将模型移动(-x, -y, -z),再旋转,最后再移动(x, y, z)将模型移回原位置!下面我们就以上一节旋转高达模型为例,讲解其矩阵的来源。

        第一步:通过遍历所有的点坐标,我们可以知道改模型的中心点大概在(450, 500, 0)的位置上,那么我们就需要将模型移动(-450, -500, 0),将旋转点移到坐标系原点,可得该步骤的矩阵为

        第二步:我们将模型绕着Y轴旋转-45°,可得到该步骤的矩阵为

        第三部:将旋转后的模型移回原来的位置,可得该步骤矩阵为

        所以我们最后将这3个矩阵进行累乘,即可得到我们最后的结果

        矩阵讲解先告一段落,后续我们还将讲解另外一种矩阵----透视投影矩阵,以及鼠标交互时还会设计矩阵的其他知识,下一章我们将使用纹理贴图给高达模型穿上皮肤。

完整代码见开头的资源下载,模型数据见上一章​​​​​​​的下载

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

kubernetes镜像仓库harbor

一、镜像仓库的种类 GitHub GitHub有付费版和免费版,目前默认的docker镜像拉取策略是从GitHub上进行拉取gitee 国内harbor私有仓库二、harbor仓库规划设计 私有镜像仓库 Harbor 安装和配置 新创建一台虚拟机安装harbor, 配置如下: 主机名ip配置网络harbor192.168.1.204VCPU/…

【数据库】索引的使用

【数据库】索引的使用 前言出发示例创建表Explain 查看sql执行计划where 查询解析无索引有索引 where oderBy 查询解析无索引有索引 总结 前言 在数据库设计过程中&#xff0c;常需要考虑性能&#xff0c;好的设计可以大大提高sql 语句的增删改查速度。在表的创建过程中&…

【linux温故】CFS调度

写在前面 网上关于CFS 调度器的文章多如牛毛&#xff0c;没必要自己写。很多文章写的都非常好。 很多文章里&#xff0c;关键的技术点&#xff0c;都是一样的&#xff0c;只是各个文章说法不一样。 掌握了核心的&#xff0c;关键的&#xff0c;其他的&#xff0c;如果工作中…

【5G NR】【一文读懂系列】移动通讯中使用的信道编解码技术-卷积码原理

目录 一、引言 二、卷积编码的发展历史 2.1 卷积码的起源 2.2 主要发展阶段 2.3 重要里程碑 三、卷积编码的基本概念 3.1 基本定义 3.2 编码器框图 3.3 编码多项式 3.4 网格图(Trellis)描述 四、MATLAB示例 一、引言 卷积编码&#xff0c;作为数字通信领域中的一项…

C++,stl,栈stack和队列queue详解

1.栈stack 1.stack基本概念 2.stack常用接口 代码示例&#xff1a; #include<bits/stdc.h> using namespace std;int main() {stack<int> stk;stk.push(7);stk.push(9);stk.push(5);cout << "栈的size为&#xff1a;" << stk.size() <…

机器学习系列——(十九)层次聚类

引言 在机器学习和数据挖掘领域&#xff0c;聚类算法是一种重要的无监督学习方法&#xff0c;它试图将数据集中的样本分组&#xff0c;使得同一组内的样本相似度高&#xff0c;不同组间的样本相似度低。层次聚类&#xff08;Hierarchical Clustering&#xff09;是聚类算法中的…

2.7日学习打卡----初学RabbitMQ(二)

2.7日学习打卡 JMS 由于MQ产品很多&#xff0c;操作方式各有不同&#xff0c;于是JAVA提供了一套规则 ——JMS&#xff0c;用于操作消息中间件。JMS即Java消息服务 &#xff08;JavaMessage Service&#xff09;应用程序接口&#xff0c;是一个Java平台中关于面 向消息中间件的…

Spring Boot整合MyBatis Plus实现基本CRUD与高级功能

文章目录 1. 引言2. 项目搭建与依赖配置2.1 添加MyBatis Plus依赖2.2 配置数据源与MyBatis Plus 3. 实现基本CRUD功能3.1 创建实体类3.2 创建Mapper接口3.3 实现Service层3.4 控制器实现 4. 高级功能实现4.1 自动填充功能4.2 乐观锁功能4.3 逻辑删除功能 5. 拓展&#xff1a;My…

EasyExcel操作Excel表格

一、EasyExcel介绍 1.1 介绍 EasyExcel 是一个基于 Java 的简单易用的 Excel 文件读写工具&#xff0c;它提供了一种简单而又高效的方式来读取、写入和操作 Excel 文件。EasyExcel 是阿里巴巴开源的项目&#xff0c;它旨在简化开发人员处理 Excel 文件的流程&#xff0c;使得…

【漏洞复现】狮子鱼CMS某SQL注入漏洞01

Nx01 产品简介 狮子鱼CMS&#xff08;Content Management System&#xff09;是一种网站管理系统&#xff0c;它旨在帮助用户更轻松地创建和管理网站。该系统拥有用户友好的界面和丰富的功能&#xff0c;包括页面管理、博客、新闻、产品展示等。通过简单直观的管理界面&#xf…

【JavaScript 漫游】【013】Date 对象知识点摘录

文章简介 本文为【JavaScript 漫游】专栏的第 013 篇文章&#xff0c;记录了 JS 语言中 Date 对象的重要知识点。 普通函数的用法构造函数的用法日期的运算静态方法&#xff0c;包括&#xff1a;Date.now()、Date.parse() 和 Date.UTC()实例方法&#xff0c;包括&#xff1a;…

初识文件包含漏洞

目录 什么是文件包含漏洞&#xff1f; 文件包含的环境要求 常见的文件包含函数 PHP伪协议 file://协议 php://协议 php://filter php://input zip://、bzip2://、zlib://协议 zip:// bzip2:// zlib:// data://协议 文件包含漏洞演示 案例1&#xff1a;php://inp…

使用 Elasticsearch 和 OpenAI 构建生成式 AI 应用程序

本笔记本演示了如何&#xff1a; 将 OpenAI Wikipedia 向量数据集索引到 Elasticsearch 中使用 Streamlit 构建一个简单的 Gen AI 应用程序&#xff0c;该应用程序使用 Elasticsearch 检索上下文并使用 OpenAI 制定答案 安装 安装 Elasticsearch 及 Kibana 如果你还没有安装好…

静态时序分析:工艺库的特征化条件和工作条件

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 一个工艺库(technology library) 会指定该库的特征化条件(characterization condition)和工作条件(operating condition)。一般在工艺库的开头会看见以下信息。 …

5.1 灯光色彩与视觉

5.1 灯光色彩与视觉 视觉成像 灯光与物体的反应:吸收,反射和折射 色彩:光照到物体上,物体吸收其他光源色,只反射该颜色光,所以物体 表面呈现该颜色 视觉:该颜色光进入人眼刺激感光细胞,并在视网膜上形成影像. ABSORBTION 一、基础灯光 1.环境光&#xff08;Ambient Light…

电商小程序05用户注册

目录 1 搭建页面2 设置默认跳转总结 我们上一篇拆解了登录功能&#xff0c;如果用户没有账号就需要注册了。本篇我们介绍一下注册功能的实现。 1 搭建页面 打开应用&#xff0c;点击左上角的新建页面 输入页面的名称&#xff0c;用户注册 删掉网格布局&#xff0c;添加表单容…

华为OD机试 - 智能成绩表( Python C C++ JavaGo JS PHP)

题目描述 小明是一名新老师&#xff0c;他需要将学生按考试总分或单科分数进行排名。学生的信息包括姓名、科目和对应的分数。帮助小明完成这个任务吧&#xff01; 输入描述 第一行包含两个整数 n 和 m&#xff0c;分别代表学生人数和科目数量。 0 < n < 1000 < m &…

【Makefile语法 01】程序编译与执行

目录 一、编译原理概述 二、编译过程分析 三、编译动静态库 四、执行过程分析 一、编译原理概述 make&#xff1a; 一个GCC工具程序&#xff0c;它会读 makefile 脚本来确定程序中的哪个部分需要编译和连接&#xff0c;然后发布必要的命令。它读出的脚本&#xff08;叫做 …

Mysql Day03

多表设计 一对多 在多的一方添加外键约束&#xff0c;关联另外一方主键 一对一 任意一方添加外键约束&#xff0c;关联另外一方主键 多对多 建立第三张中间表&#xff0c;中间表至少包含两个外键&#xff0c;分别关联两方主键 idstu_idcourse_id 1 11 2 12313421524 案…

传输频宽是啥?对网速影响有多大?

频宽&#xff0c;即WIFI频道宽度&#xff0c;又称为WIFI信道宽度&#xff0c;是WiFi Channel width的缩写。从科学的定义来说&#xff0c;Wi-Fi频道宽度&#xff0c;是指Wi-Fi无线信号在频谱上所占用的带宽大小。它决定了Wi-Fi网络的数据传输速率和稳定性&#xff0c;一般有20M…