4x4矩阵教程

4x4矩阵教程

1. 简介

四维矩阵是计算机图形学和3D变换中的重要工具,用于表示三维空间中的仿射变换。本教程将介绍如何使用C++实现四维矩阵的基本运算和变换。

2. 代码实现

2.1 头文件 (matrix4x4.h)

#ifndef MATRIX4X4_H
#define MATRIX4X4_H#include <array>
#include <stdexcept>
#include <iostream>namespace math {
namespace linear_algebra {/*** @brief 四维矩阵类* * 这个类实现了四维矩阵的基本运算,包括:* - 矩阵加减* - 矩阵乘法* - 标量乘法* - 行列式计算* - 矩阵求逆* - 矩阵转置* - 特征值和特征向量计算* - 矩阵性质检查(可逆性、对称性、正交性)* - 特殊矩阵生成(旋转矩阵、缩放矩阵、平移矩阵、投影矩阵等)*/
class Matrix4x4 {
public:// 构造函数Matrix4x4();  // 默认构造函数,初始化为单位矩阵Matrix4x4(const std::array<std::array<double, 4>, 4>& data);  // 从二维数组初始化// 基本运算Matrix4x4 operator+(const Matrix4x4& other) const;  // 矩阵加法Matrix4x4 operator-(const Matrix4x4& other) const;  // 矩阵减法Matrix4x4 operator*(const Matrix4x4& other) const;  // 矩阵乘法Matrix4x4 operator*(double scalar) const;           // 标量乘法Matrix4x4 operator/(double scalar) const;           // 标量除法// 矩阵运算double determinant() const;                         // 计算行列式Matrix4x4 inverse() const;                          // 计算逆矩阵Matrix4x4 transpose() const;                        // 计算转置矩阵std::array<double, 4> eigenvalues() const;          // 计算特征值std::array<Matrix4x4, 4> eigenvectors() const;      // 计算特征向量// 矩阵性质bool isInvertible() const;                          // 检查是否可逆bool isSymmetric() const;                           // 检查是否对称bool isOrthogonal() const;                          // 检查是否正交// 特殊矩阵static Matrix4x4 identity();                        // 创建单位矩阵static Matrix4x4 rotation(double theta, char axis); // 创建旋转矩阵static Matrix4x4 scaling(double sx, double sy, double sz); // 创建缩放矩阵static Matrix4x4 translation(double tx, double ty, double tz); // 创建平移矩阵static Matrix4x4 perspective(double fov, double aspect, double near, double far); // 创建透视投影矩阵static Matrix4x4 orthographic(double left, double right, double bottom, double top, double near, double far); // 创建正交投影矩阵// 输出运算符friend std::ostream& operator<<(std::ostream& os, const Matrix4x4& m);private:std::array<std::array<double, 4>, 4> data;  // 4x4矩阵数据
};} // namespace linear_algebra
} // namespace math#endif // MATRIX4X4_H

2.2 实现文件 (matrix4x4.cpp)

#include "matrix4x4.h"
#include <cmath>namespace math {
namespace linear_algebra {// 默认构造函数:初始化为单位矩阵
Matrix4x4::Matrix4x4() {for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {data[i][j] = (i == j) ? 1.0 : 0.0;}}
}// 从二维数组初始化
Matrix4x4::Matrix4x4(const std::array<std::array<double, 4>, 4>& data) : data(data) {}// 矩阵加法实现
Matrix4x4 Matrix4x4::operator+(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] + other.data[i][j];}}return result;
}// 矩阵减法实现
Matrix4x4 Matrix4x4::operator-(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] - other.data[i][j];}}return result;
}// 矩阵乘法实现
Matrix4x4 Matrix4x4::operator*(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = 0.0;for (int k = 0; k < 4; ++k) {result.data[i][j] += data[i][k] * other.data[k][j];}}}return result;
}// 标量乘法实现
Matrix4x4 Matrix4x4::operator*(double scalar) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] * scalar;}}return result;
}// 标量除法实现
Matrix4x4 Matrix4x4::operator/(double scalar) const {if (scalar == 0.0) {throw std::runtime_error("Division by zero");}return *this * (1.0 / scalar);
}// 行列式计算实现
double Matrix4x4::determinant() const {// 使用拉普拉斯展开计算4x4矩阵的行列式double det = 0.0;for (int i = 0; i < 4; ++i) {double cofactor = 0.0;for (int j = 0; j < 4; ++j) {if ((i + j) % 2 == 0) {cofactor += data[0][j] * minor(0, j);} else {cofactor -= data[0][j] * minor(0, j);}}det += data[0][i] * cofactor;}return det;
}// 逆矩阵计算实现
Matrix4x4 Matrix4x4::inverse() const {double det = determinant();if (det == 0.0) {throw std::runtime_error("Matrix is not invertible");}Matrix4x4 result;double invDet = 1.0 / det;// 计算伴随矩阵for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = cofactor(j, i) * invDet;}}return result;
}// 转置矩阵实现
Matrix4x4 Matrix4x4::transpose() const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[j][i];}}return result;
}// 特征值计算实现
std::array<double, 4> Matrix4x4::eigenvalues() const {// 计算特征多项式系数// 这里使用简化的方法,实际应用中可能需要更复杂的数值方法std::array<double, 4> roots;// ... 求解四次方程的代码 ...return roots;
}// 特征向量计算实现
std::array<Matrix4x4, 4> Matrix4x4::eigenvectors() const {std::array<double, 4> eigenvals = eigenvalues();std::array<Matrix4x4, 4> eigenvecs;// ... 计算特征向量的代码 ...return eigenvecs;
}// 可逆性检查实现
bool Matrix4x4::isInvertible() const {return determinant() != 0.0;
}// 对称性检查实现
bool Matrix4x4::isSymmetric() const {for (int i = 0; i < 4; ++i) {for (int j = i + 1; j < 4; ++j) {if (data[i][j] != data[j][i]) {return false;}}}return true;
}// 正交性检查实现
bool Matrix4x4::isOrthogonal() const {Matrix4x4 product = *this * transpose();Matrix4x4 identity = Matrix4x4::identity();for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {if (std::abs(product.data[i][j] - identity.data[i][j]) > 1e-10) {return false;}}}return true;
}// 单位矩阵创建实现
Matrix4x4 Matrix4x4::identity() {return Matrix4x4();
}// 旋转矩阵创建实现
Matrix4x4 Matrix4x4::rotation(double theta, char axis) {Matrix4x4 result;double cos_theta = std::cos(theta);double sin_theta = std::sin(theta);switch (axis) {case 'x':result.data[1][1] = cos_theta;result.data[1][2] = -sin_theta;result.data[2][1] = sin_theta;result.data[2][2] = cos_theta;break;case 'y':result.data[0][0] = cos_theta;result.data[0][2] = sin_theta;result.data[2][0] = -sin_theta;result.data[2][2] = cos_theta;break;case 'z':result.data[0][0] = cos_theta;result.data[0][1] = -sin_theta;result.data[1][0] = sin_theta;result.data[1][1] = cos_theta;break;default:throw std::runtime_error("Invalid rotation axis");}return result;
}// 缩放矩阵创建实现
Matrix4x4 Matrix4x4::scaling(double sx, double sy, double sz) {Matrix4x4 result;result.data[0][0] = sx;result.data[1][1] = sy;result.data[2][2] = sz;return result;
}// 平移矩阵创建实现
Matrix4x4 Matrix4x4::translation(double tx, double ty, double tz) {Matrix4x4 result;result.data[0][3] = tx;result.data[1][3] = ty;result.data[2][3] = tz;return result;
}// 透视投影矩阵创建实现
Matrix4x4 Matrix4x4::perspective(double fov, double aspect, double near, double far) {Matrix4x4 result;double tan_half_fov = std::tan(fov / 2.0);result.data[0][0] = 1.0 / (aspect * tan_half_fov);result.data[1][1] = 1.0 / tan_half_fov;result.data[2][2] = -(far + near) / (far - near);result.data[2][3] = -1.0;result.data[3][2] = -(2.0 * far * near) / (far - near);result.data[3][3] = 0.0;return result;
}// 正交投影矩阵创建实现
Matrix4x4 Matrix4x4::orthographic(double left, double right, double bottom, double top, double near, double far) {Matrix4x4 result;result.data[0][0] = 2.0 / (right - left);result.data[1][1] = 2.0 / (top - bottom);result.data[2][2] = -2.0 / (far - near);result.data[0][3] = -(right + left) / (right - left);result.data[1][3] = -(top + bottom) / (top - bottom);result.data[2][3] = -(far + near) / (far - near);return result;
}// 输出运算符实现
std::ostream& operator<<(std::ostream& os, const Matrix4x4& m) {for (int i = 0; i < 4; ++i) {os << "[ ";for (int j = 0; j < 4; ++j) {os << m.data[i][j] << " ";}os << "]" << std::endl;}return os;
}} // namespace linear_algebra
} // namespace math

3. 使用示例

3.1 基本运算

#include "matrix4x4.h"
#include <iostream>using namespace math::linear_algebra;int main() {// 创建矩阵Matrix4x4 m1({{{1.0, 2.0, 3.0, 4.0},{5.0, 6.0, 7.0, 8.0},{9.0, 10.0, 11.0, 12.0},{13.0, 14.0, 15.0, 16.0}}});Matrix4x4 m2({{{16.0, 15.0, 14.0, 13.0},{12.0, 11.0, 10.0, 9.0},{8.0, 7.0, 6.0, 5.0},{4.0, 3.0, 2.0, 1.0}}});// 基本运算Matrix4x4 sum = m1 + m2;      // 矩阵加法Matrix4x4 diff = m1 - m2;     // 矩阵减法Matrix4x4 prod = m1 * m2;     // 矩阵乘法Matrix4x4 scaled = m1 * 2.0;  // 标量乘法// 输出结果std::cout << "m1:\n" << m1 << std::endl;std::cout << "m2:\n" << m2 << std::endl;std::cout << "m1 + m2:\n" << sum << std::endl;std::cout << "m1 - m2:\n" << diff << std::endl;std::cout << "m1 * m2:\n" << prod << std::endl;std::cout << "m1 * 2:\n" << scaled << std::endl;return 0;
}

3.2 3D变换

#include "matrix4x4.h"
#include <iostream>
#include <cmath>using namespace math::linear_algebra;int main() {// 创建变换矩阵Matrix4x4 rotation = Matrix4x4::rotation(M_PI / 4.0, 'z');  // 绕Z轴旋转45度Matrix4x4 scaling = Matrix4x4::scaling(2.0, 3.0, 4.0);      // 缩放Matrix4x4 translation = Matrix4x4::translation(1.0, 2.0, 3.0); // 平移// 组合变换(注意顺序:先缩放,再旋转,最后平移)Matrix4x4 transform = translation * rotation * scaling;// 创建投影矩阵Matrix4x4 perspective = Matrix4x4::perspective(M_PI / 4.0, 16.0/9.0, 0.1, 100.0);Matrix4x4 ortho = Matrix4x4::orthographic(-1.0, 1.0, -1.0, 1.0, 0.1, 100.0);// 输出结果std::cout << "旋转矩阵:\n" << rotation << std::endl;std::cout << "缩放矩阵:\n" << scaling << std::endl;std::cout << "平移矩阵:\n" << translation << std::endl;std::cout << "组合变换:\n" << transform << std::endl;std::cout << "透视投影:\n" << perspective << std::endl;std::cout << "正交投影:\n" << ortho << std::endl;return 0;
}

4. 编译和运行

4.1 编译

使用提供的Makefile进行编译:

make        # 编译所有目标
make test   # 运行测试
make demo   # 运行示例
make clean  # 清理编译文件

4.2 运行测试

./matrix4x4_test

4.3 运行示例

./matrix4x4_demo

5. 注意事项

  1. 数值精度

    • 在比较浮点数时使用适当的误差范围
    • 例如:std::abs(det) < 1e-10 判断是否可逆
  2. 异常处理

    • 除以零的情况
    • 不可逆矩阵求逆的情况
    • 无效的旋转轴
    • 投影参数的有效性检查
  3. 性能考虑

    • 矩阵乘法的时间复杂度为O(n³)
    • 特征值计算可能需要迭代方法
    • 考虑使用SIMD指令优化计算
    • 投影矩阵的预计算
  4. 使用建议

    • 优先使用成员函数而不是全局函数
    • 保持接口的一致性
    • 提供清晰的错误信息
    • 注意变换矩阵的组合顺序

6. 扩展阅读

  1. 线性代数基础

    • 矩阵运算
    • 行列式
    • 特征值和特征向量
  2. 3D变换

    • 旋转矩阵
    • 缩放矩阵
    • 平移矩阵
    • 投影矩阵
  3. 应用领域

    • 计算机图形学
    • 3D游戏开发
    • 计算机视觉
    • 机器人学
    • 物理模拟

    声明

该文章为学习过程中的笔记,目的是防止自己忘记,也为了方便随时随地查阅。其中大部分内容收集于互联网。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle 数据库共享池与大池调优指南

在 Oracle 数据库的内存管理中&#xff0c;共享池&#xff08;Shared Pool&#xff09;和大池&#xff08;Large Pool&#xff09;是 SGA&#xff08;系统全局区&#xff09;中负责缓存与资源分配的核心组件。合理配置和调优这两个池&#xff0c;能显著提升数据库性能 —— 尤其…

C# Lambdab表达式 Var 类

Lambdab 是用于创建一个方法的表达式Func<参数1类型, 参数2类型, 返回值类型> fnName >(参数1 参数2) {方法代码体}Func<int, int, bool> fnName (int a, int b) > {return a > b; };//调用时和普通方法一致 Console.WriteLine(fnName(10,20)); // false…

【Python】常见模块及其用法

文章目录1. 什么是模块和包&#xff1f;2. 常见的模块及其用法2.1 time概览2.1.1 时间获取方法2.1.2 时间格式化与解析2.1.3 程序计时与延迟2.1.4 时间转换2.2 random概览2.2.1 基本随机数2.2.2 随机整数2.2.3 序列操作2.2.4 概率分布2.2.5 随机种子2.2.6 状态管理2.3 os概览2.…

洛谷 P3478 [POI 2008] STA-Station

【题目链接】 洛谷 P3478 [POI 2008] STA-Station 【题目考点】 1. 树形动规&#xff1a;换根动规 换根动规&#xff0c;又名二次扫描法&#xff0c;一般是给一颗不定根树&#xff0c;通过两次扫描来求解。 我们可以先任选一个根结点root&#xff0c;通过树形动规的思想计算…

【爬虫】03 - 爬虫的基本数据存储

爬虫03 - 爬虫的数据存储 文章目录爬虫03 - 爬虫的数据存储一&#xff1a;CSV数据存储1&#xff1a;基本介绍2&#xff1a;基本使用3&#xff1a;高级使用4&#xff1a;使用示例二&#xff1a;JSON数据存储1&#xff1a;基础json读写2&#xff1a;字符串和对象的转换3&#xff…

深入分析计算机网络数据链路层和网络层面试题

计算机网络体系结构1. 请简述 OSI 七层模型和 TCP/IP 四层模型&#xff0c;并比较它们的异同。OSI 七层模型&#xff1a;应用层&#xff1a;直接为用户的应用进程提供服务&#xff0c;如 HTTP&#xff08;超文本传输协议&#xff0c;用于 Web 浏览器与服务器通信&#xff09;、…

云服务器新装的mysql8,无法通过远程连接,然后本地pymysql也连不上

阿里云服务器&#xff0c;用apt-get新装的mysql-server&#xff0c;竟然无法通过远程连接到&#xff0c;竟然是这个原因。不是防火墙&#xff0c;iptables早就关了。也不是安全组&#xff0c;不是人为限制访问的话&#xff0c;根本没必要弄安全组 排查过程 netstat -antop|grep…

质量即服务:从测试策略到平台运营的全链路作战手册

&#xff08;零&#xff09;为什么需要“质量即服务” 当业务方说“今晚一定要上线”&#xff0c; 当开发说“我只改了两行代码”&#xff0c; 当运维说“回滚窗口只有 5 分钟”&#xff0c; 质量必须像水电一样随取随用&#xff0c;而不是上线前的大坝泄洪。 这篇手册提供一张…

Java -- 自定义异常--Wrapper类--String类

自定义异常&#xff1a;概念&#xff1a;当程序中出现了某些错误&#xff0c;但该错误信息并没有在Throwable子类中描述处理&#xff0c;这个时候可以自己设计异常&#xff0c;用于描述该错误信息。步骤&#xff1a;1. 定义类&#xff1a;自定义异常类名&#xff08;程序员自己…

一文速通《线性方程组》

目录 一、解题必记知识点 二、解题必备技巧 三、非齐次线性方程组求解 四、齐次线性方程组求解 ★五、解析题目信息&#xff0c;获取暗含条件 一、解题必记知识点 (1) (2)基础解系线性无关&#xff0c;基础解系 解空间的一个基&#xff0c;基 一组线性无关的、能够生…

【Django】DRF API版本和解析器

讲解 Python3 下 Django REST Framework (DRF) API 版本控制解析器&#xff08;Parser&#xff09;一、DRF API 版本控制详解 API 版本控制是构建健壮、可维护的 RESTful API 的关键&#xff0c;尤其在项目演进中需要兼容不同版本的客户端请求。 1.1 API 版本控制的核心原理 AP…

Windows系统暂停更新工具

功能说明 暂停更新至2999年恢复系统更新彻底禁用更新&#xff08;不可逆&#xff09; 使用方法 下载解压后双击运行 .bat 文件 输入数字选择功能&#xff1a; 输入 1&#xff1a;暂停更新至2999年&#xff08;推荐&#xff09;输入 2&#xff1a;恢复系统更新输入 3&#xf…

git push新版问题解决

git 好像不能通过username:password的方式来git push了。但我的电脑依然弹出username和password的弹窗。转战ssh来git push。由于之前是用git clone克隆的&#xff0c;需要再转换成ssh的url来git push。

PyCharm + AI 辅助编程

PyCharm AI&#xff1a;初学者友好的 2 个实用场景&#xff08;附操作步骤&#xff09; PyCharm 专业版&#xff08;或通过插件集成&#xff09;支持 AI 辅助编程&#xff08;如 JetBrains AI 或 GitHub Copilot&#xff09;&#xff0c;能根据代码上下文自动生成代码、解释逻…

疯狂星期四文案网第15天运营日记

网站运营第15天&#xff0c;点击观站&#xff1a; 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 昨日访问量 昨天只有20来ip, 太惨了&#xff0c;感觉和最近没有发新段子有关&#xff0c;也没有发新的外链&#xff0c;不知道这周四会怎么样 昨日搜…

如何解决pip安装报错ModuleNotFoundError: No module named ‘Cython’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘Cython’问题 摘要 在使用 PyCharm 控制台或命令行执行 pip install Cython 时&#xff0c;常会遇到 ModuleNotFoundError: No module named Cython 的报错。本…

freertos任务调度关键函数理解 vTaskSwitchContext

void vTaskSwitchContext(void) {//my_printf( "uxSchedulerSuspended %d\n", uxSchedulerSuspended );/* 调度器处于挂起状态 */if (uxSchedulerSuspended ! (UBaseType_t)pdFALSE) {/*** The scheduler is currently suspended - do not allow a context* switch.…

CPU 密集型 和 I/O 密集型 任务

文章目录**CPU 密集型任务&#xff08;CPU-bound&#xff09;**定义&#xff1a;特点&#xff1a;常见场景&#xff1a;如何优化 CPU 密集型任务&#xff1a;**I/O 密集型任务&#xff08;I/O-bound&#xff09;**定义&#xff1a;特点&#xff1a;常见场景&#xff1a;如何优化…

[2025CVPR-小目标检测方向]基于特征信息驱动位置高斯分布估计微小目标检测模型

核心问题 ​小目标检测性能差&#xff1a;​​ 尽管通用目标检测器&#xff08;如 Faster R-CNN, YOLO, SSD&#xff09;在常规目标上表现出色&#xff0c;但在检测微小目标&#xff08;如 AI-TOD 基准定义的&#xff1a;非常小目标 2-8 像素&#xff0c;小目标 8-16 像素&…

三大工厂设计模式

1.简单工厂模式1.1需求入手从需求进行入手&#xff0c;可以更深入的理解什么是设计模式。有一个制作披萨的需求&#xff1a;需要便于扩展披萨的种类&#xff0c;便于维护。1.披萨的种类有很多&#xff1a;GreekPizz&#xff0c;CheesePizz等2.披萨的制作流程&#xff1a;prepar…