线性代数:Matrix2x2和Matrix3x3

      今天整理自己的框架代码,将Matrix2x2和Matrix3x3给扩展了一下,发现网上unity数学计算相关挺少的,所以记录一下。
      首先扩展Matrix2x2:

using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;public class Matrix2x2
{#region ///propertiespublic const int ROW = 2;public const int COLUMN = 2;public float M00{get { return dataArr[0, 0]; }set { dataArr[0, 0] = value; }}public float M01{get { return dataArr[0, 1]; }set { dataArr[0, 1] = value; }}public float M10{get { return dataArr[1, 0]; }set { dataArr[1, 0] = value; }}public float M11{get { return dataArr[1, 1]; }set { dataArr[1, 1] = value; }}private float[,] dataArr = new float[ROW, COLUMN];public Vector2 Row0 { get { return new Vector2(M00, M01); } }public Vector2 Row1 { get { return new Vector2(M10, M11); } }public Vector2 Column0 { get { return new Vector2(M00, M10); } }public Vector2 Column1 { get { return new Vector2(M01, M11); } }#endregionpublic float this[int row, int col]{get { return dataArr[row, col]; }set { dataArr[row, col] = value; }}public Matrix2x2() { }public Matrix2x2(float m00, float m01, float m10, float m11){M00 = m00;M01 = m01;M10 = m10;M11 = m11;}/// <summary>/// xy基向量/// 竖向排列/// </summary>/// <param name="ax"></param>/// <param name="ay"></param>public Matrix2x2(Vector2 ax, Vector2 ay){M00 = ax.x;M10 = ax.y;M10 = ay.x;M11 = ay.y;}/// <summary>/// 2*2数组/// </summary>/// <param name="arr"></param>public Matrix2x2(float[,] arr){M00 = arr[0, 0];M01 = arr[0, 1];M10 = arr[1, 0];M11 = arr[1, 1];}/// <summary>/// 矩阵*vector2/// </summary>/// <param name="m2x2"></param>/// <param name="v2"></param>/// <returns></returns>public static Vector2 operator *(Matrix2x2 m2x2, Vector2 v2){float x = Vector2.Dot(m2x2.Row0, v2);float y = Vector2.Dot(m2x2.Row1, v2);return new Vector2(x, y);}/// <summary>/// 矩阵*矩阵/// </summary>/// <param name="m2x2a"></param>/// <param name="m2x2b"></param>/// <returns></returns>public static Matrix2x2 operator *(Matrix2x2 m2x2a, Matrix2x2 m2x2b){float c00 = Vector2.Dot(m2x2a.Row0, m2x2b.Column0);float c01 = Vector2.Dot(m2x2a.Row0, m2x2b.Column1);float c10 = Vector2.Dot(m2x2a.Row1, m2x2b.Column0);float c11 = Vector2.Dot(m2x2a.Row1, m2x2b.Column1);Matrix2x2 ret = new Matrix2x2(c00, c01, c10, c11);return ret;}/// <summary>/// 矩阵/标量/// </summary>/// <param name="m2x2"></param>/// <param name="f"></param>/// <returns></returns>public static Matrix2x2 operator /(Matrix2x2 m2x2, float f){for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){m2x2[x, y] /= f;}}return m2x2;}/// <summary>/// 行列式/// </summary>/// <returns></returns>public float GetDeterminant(){float det = M00 * M11 - M01 * M10;return det;}/// <summary>/// 求转置矩阵/// </summary>/// <returns></returns>public Matrix2x2 GetTransposeMatrix(){Matrix2x2 m2x2T = new Matrix2x2();for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){m2x2T[x, y] = this[y, x];}}return m2x2T;}/// <summary>/// 求余子式标量/// </summary>/// <param name="r"></param>/// <param name="c"></param>/// <returns></returns>public float GetCofactorScalar(int r, int c){float cof = 0f;for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){if (x != r && y != c){cof = dataArr[x, y];break;}}}return cof;}/// <summary>/// 求余子式标量矩阵/// + -/// - +/// </summary>/// <returns></returns>public Matrix2x2 GetCofactorScalarMatrix(){Matrix2x2 m2x2 = new Matrix2x2();for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){float cof = GetCofactorScalar(x, y);bool ispostive = (x + y) % 2 == 0;m2x2[x, y] = ispostive ? cof : -cof;}}return m2x2;}/// <summary>/// 求伴随矩阵/// 算法:余子式标量矩阵的转置/// </summary>/// <returns></returns>public Matrix2x2 GetAdjointMatrix(){Matrix2x2 m2x2 = GetCofactorScalarMatrix();Matrix2x2 m2x2T = m2x2.GetTransposeMatrix();return m2x2T;}/// <summary>/// 求逆矩阵/// 算法:伴随矩阵/行列式值/// </summary>/// <returns></returns>public Matrix2x2 GetInverseMatrix(){Matrix2x2 m2x2 = GetAdjointMatrix();float det = GetDeterminant();Matrix2x2 m2x2I = m2x2 / det;return m2x2I;}public override string ToString(){string ret = $"换行\nM00:{M00} M01:{M01} \nM10:{M10} M11:{M11}";return ret;}
}

      关于Matrix2x2,我设计了构造、转置、余子式(2x2矩阵的余子式为标量,或称1x1矩阵)、余子式标量矩阵、伴随矩阵和逆矩阵。
      基本上数学运算开发够用了,每个函数的意义只在代码注释上简单说明。
      这里只举一个例子:逆矩阵可以将矩阵变换后向量再变换回来,比如:

Matrix2x2 m2x2 = new Matrix2x2();
m2x2.M00 = 0.3f;
m2x2.M01 = 1.2f;
m2x2.M10 = 5.2f;
m2x2.M11 = -1f;Debug.LogErrorFormat($"m2x2 = {m2x2}");Vector2 vec0 = new Vector2(5.8f, 56.1f);Vector2 vec1 = m2x2 * vec0;Matrix2x2 m2x2I = m2x2.GetInverseMatrix();Debug.LogErrorFormat($"m2x2I = {m2x2I}");Vector2 vec2 = m2x2I * vec1;Debug.LogErrorFormat($"vec0 = {vec0} vec1 = {vec1} vec2 = {vec2}");

      结果:
在这里插入图片描述
      接下来扩展Matrix3x3:

using NPOI.SS.Formula.Functions;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Matrix3x3
{#region ///propertiespublic const int ROW = 3;public const int COLUMN = 3;public float M00{get { return dataArr[0, 0]; }set { dataArr[0, 0] = value; }}public float M01{get { return dataArr[0, 1]; }set { dataArr[0, 1] = value; }}public float M02{get { return dataArr[0, 2]; }set { dataArr[0, 2] = value; }}public float M10{get { return dataArr[1, 0]; }set { dataArr[1, 0] = value; }}public float M11{get { return dataArr[1, 1]; }set { dataArr[1, 1] = value; }}public float M12{get { return dataArr[1, 2]; }set { dataArr[1, 2] = value; }}public float M20{get { return dataArr[2, 0]; }set { dataArr[2, 0] = value; }}public float M21{get { return dataArr[2, 1]; }set { dataArr[2, 1] = value; }}public float M22{get { return dataArr[2, 2]; }set { dataArr[2, 2] = value; }}public float[,] dataArr = new float[ROW, COLUMN];public Vector3 Row0 { get { return new Vector3(M00, M01, M02); } }public Vector3 Row1 { get { return new Vector3(M10, M11, M12); } }public Vector3 Row2 { get { return new Vector3(M20, M21, M22); } }public Vector3 Column0 { get { return new Vector3(M00, M10, M20); } }public Vector3 Column1 { get { return new Vector3(M01, M11, M21); } }public Vector3 Column2 { get { return new Vector3(M02, M12, M22); } }#endregionpublic float this[int row, int col]{get { return dataArr[row, col]; }set { dataArr[row, col] = value; }}public Matrix3x3() { }public Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22){M00 = m00;M01 = m01;M02 = m02;M10 = m10;M11 = m11;M12 = m12;M20 = m20;M21 = m21;M22 = m22;}/// <summary>/// xyz基向量排列/// </summary>/// <param name="ax">x基向量</param>/// <param name="ay">y基向量</param>/// <param name="az">z基向量</param>public Matrix3x3(Vector3 ax, Vector3 ay, Vector3 az){M00 = ax.x;M10 = ax.y;M20 = ax.z;M01 = ay.x;M11 = ay.y;M21 = ay.z;M02 = az.x;M12 = az.y;M22 = az.z;}/// <summary>/// 数组排列/// </summary>/// <param name="arr"></param>public Matrix3x3(float[,] arr){M00 = arr[0, 0];M01 = arr[0, 1];M02 = arr[0, 2];M10 = arr[1, 0];M11 = arr[1, 1];M12 = arr[1, 2];M20 = arr[2, 0];M21 = arr[2, 1];M22 = arr[2, 2];}/// <summary>/// 矩阵*vector2/// </summary>/// <param name="m3x3"></param>/// <param name="v2"></param>/// <returns></returns>public static Vector2 operator *(Matrix3x3 m3x3, Vector2 v2){Vector3 v3 = new Vector3(v2.x, v2.y, 1);v3 = m3x3 * v3;v2 = new Vector2(v3.x, v3.y);return v2;}/// <summary>/// 矩阵*vector3/// </summary>/// <param name="m3x3"></param>/// <param name="v3"></param>/// <returns></returns>public static Vector3 operator *(Matrix3x3 m3x3, Vector3 v3){float x = Vector3.Dot(m3x3.Row0, v3);float y = Vector3.Dot(m3x3.Row1, v3);float z = Vector3.Dot(m3x3.Row2, v3);return new Vector3(x, y, z);}/// <summary>/// 矩阵*矩阵/// </summary>/// <param name="m3x3a"></param>/// <param name="m3x3b"></param>/// <returns></returns>public static Matrix3x3 operator *(Matrix3x3 m3x3a, Matrix3x3 m3x3b){float c00 = Vector2.Dot(m3x3a.Row0, m3x3b.Column0);float c01 = Vector2.Dot(m3x3a.Row0, m3x3b.Column1);float c02 = Vector2.Dot(m3x3a.Row0, m3x3b.Column2);float c10 = Vector2.Dot(m3x3a.Row1, m3x3b.Column0);float c11 = Vector2.Dot(m3x3a.Row1, m3x3b.Column1);float c12 = Vector2.Dot(m3x3a.Row1, m3x3b.Column2);float c20 = Vector2.Dot(m3x3a.Row2, m3x3b.Column0);float c21 = Vector2.Dot(m3x3a.Row2, m3x3b.Column1);float c22 = Vector2.Dot(m3x3a.Row2, m3x3b.Column2);Matrix3x3 ret = new Matrix3x3(c00, c01, c02, c10, c11, c12, c20, c21, c22);return ret;}/// <summary>/// 矩阵/标量/// </summary>/// <param name="m3x3"></param>/// <param name="f"></param>/// <returns></returns>public static Matrix3x3 operator /(Matrix3x3 m3x3, float f){for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){m3x3[x, y] /= f;}}return m3x3;}/// <summary>/// 求行列式/// </summary>/// <returns></returns>public float GetDeterminant(){float det = M00 * M11 * M22 + M01 * M12 * M20 + M02 * M10 * M21 - M02 * M11 * M20 - M01 * M10 * M22 - M00 * M12 * M21;return det;}/// <summary>/// 求转置矩阵/// </summary>/// <returns></returns>public Matrix3x3 GetTransposeMatrix(){Matrix3x3 m3x3T = new Matrix3x3();for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){m3x3T[x, y] = this[y, x];}}return m3x3T;}/// <summary>/// 求余子式矩阵/// </summary>/// <param name="r"></param>/// <param name="c"></param>/// <returns></returns>public Matrix2x2 GetCofactorMatrix(int r, int c){Matrix2x2 m2x2 = new Matrix2x2();for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){if (x != r && y != c){int row = x > r ? x - 1 : x;int col = y > c ? y - 1 : y;m2x2[row, col] = this[x, y];}}}return m2x2;}/// <summary>/// 求代数余子式(余子式矩阵的行列式)矩阵/// 余子式矩阵行列式正负号/// + - +/// - + -/// + - +/// </summary>/// <returns></returns>public Matrix3x3 GetCofactorDeterminantMatrix(){Matrix3x3 m3x3 = new Matrix3x3();for (int x = 0; x < ROW; x++){for (int y = 0; y < COLUMN; y++){Matrix2x2 m2x2 = GetCofactorMatrix(x, y);float m2x2det = m2x2.GetDeterminant();bool ispostive = (x + y) % 2 == 0;m3x3[x, y] = ispostive ? m2x2det : -m2x2det;}}return m3x3;}/// <summary>/// 求伴随矩阵/// 算法:代数余子式矩阵的转置/// </summary>/// <returns></returns>public Matrix3x3 GetAdjointMatrix(){Matrix3x3 m3x3 = GetCofactorDeterminantMatrix();Matrix3x3 m3x3T = m3x3.GetTransposeMatrix();return m3x3T;}/// <summary>/// 求逆矩阵/// 算法:伴随矩阵/行列式值/// </summary>/// <returns></returns>public Matrix3x3 GetInverseMatrix(){Matrix3x3 m3x3 = GetAdjointMatrix();float det = GetDeterminant();Matrix3x3 m3x3I = m3x3 / det;return m3x3I;}public override string ToString(){string ret = $"换行\nM00:{M00} M01:{M01} M02:{M02} \nM10:{M10} M11:{M11} M12:{M12} \nM20:{M20} M21:{M21} M12:{M22}";return ret;}
}

      还是用逆矩阵验证一下:

Matrix3x3 m3x3 = new Matrix3x3();
m3x3.M00 = -0.3f;
m3x3.M01 = 6.2f;
m3x3.M02 = 12.6f;
m3x3.M10 = 5.2f;
m3x3.M11 = -1.8f;
m3x3.M12 = 7.8f;
m3x3.M20 = -52.2f;
m3x3.M21 = 6.4f;
m3x3.M22 = -70.1f;Debug.LogErrorFormat($"m3x3 = {m3x3}");Vector3 vec0 = new Vector3(20.3f, -54f, 4.4f);Vector3 vec1 = m3x3 * vec0;Matrix3x3 m3x3I = m3x3.GetInverseMatrix();Debug.LogErrorFormat($"m3x3I = {m3x3I}");Vector3 vec2 = m3x3I * vec1;Debug.LogErrorFormat($"vec0 = {vec0} vec1 = {vec1} vec2 = {vec2}");

      结果:
在这里插入图片描述
      OK,洗了睡,这里吐槽一下:这些矩阵计算unity应该直接提供,写起来眼睛都要看瞎了。

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

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

相关文章

windows在两台机器上测试 MySQL 集群实现实时备份

在两台机器上测试 MySQL 集群实现实时备份的基本步骤&#xff1a; 一、环境准备 机器配置 确保两台机器&#xff08;假设为服务器 A 和服务器 B&#xff09;能够互相通信&#xff0c;例如它们在同一个局域网内&#xff0c;并且开放了 MySQL 通信所需的端口&#xff08;默认是 …

【stm32】RTC时钟的介绍与使用

RTC时钟的介绍与使用 一、时间戳1、Unix时间戳2、UTC/GMT3、时间戳转换 二、BKP简介及代码编写1、BKP简介2、BKP基本结构3、BKP库函数介绍&#xff1a;4、程序编写&#xff1a; 三、RTC简介及代码编写1、RTC简介2、RTC框图2、RTC基本结构3、RTC相关库函数介绍&#xff1a;4、程…

界面控件DevExpress JS ASP.NET Core v24.1亮点 - 支持Angular 18

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

如何检索 LINEMOD 数据集的相机内参

简介 BOP (Benchmark for 6D Object Pose Estimation) 是一个专为6D物体姿态估计而设计的基准测试平台。它为研究人员提供了多种数据集&#xff0c;以帮助评估和比较物体识别和姿态估计算法的性能。官方网站是 BOP&#xff0c;你可以在这里找到丰富的资源和信息。 检索 LINEM…

机器学习与数据挖掘_使用梯度下降法训练线性回归模型

目录 实验内容 实验步骤 1. 导入必要的库 2. 加载数据并绘制散点图 3. 设置模型的超参数 4. 实现梯度下降算法 5. 打印训练后的参数和损失值 6. 绘制损失函数随迭代次数的变化图 7. 绘制线性回归拟合曲线 8. 基于训练好的模型进行新样本预测 实验代码 实验结果 实验…

web——sqliabs靶场——第一关

今天开始搞这个靶场&#xff0c;从小白开始一点点学习,加油&#xff01;&#xff01;&#xff01;&#xff01; 1.搭建靶场 注意点&#xff1a;1.php的版本问题&#xff0c;要用老版本 2.小p要先改数据库的密码&#xff0c;否则一直显示链接不上数据库 2.第一道题&#xff0…

Xamarin 实现播放视频 MP4

我的想法是在App启动时播放一段视频&#xff0c;实现方式如下&#xff1a; 准备一个视频&#xff1a; Logo.mp4 添加到资源中&#xff1a;Assets 然后将资源设置为 AndroidAsset 启动时&#xff0c;将资源文件拷贝到程序目录的files下&#xff1a; protected override void On…

4070显卡只要一毛钱?这个双十一太疯狂了

2024年双十一大战正酣&#xff0c;各大商家使尽浑身解数&#xff0c;奇招频出&#xff0c;真是让人看得目瞪口呆。每日口令红包、攒火力值领裂变红包、限时抢免定金红包……还有各类满减和打折优惠活动&#xff0c;玩法千奇百怪&#xff0c;算来算去索性放弃&#xff0c;真是没…

C++优选算法四 前缀和

前缀和算法是一种常用的优化技术&#xff0c;主要用于加速某些涉及连续子数组或子序列求和的问题。 一、定义与原理 定义&#xff1a;前缀和是指数组中某个位置之前&#xff08;包括该位置&#xff09;所有元素的和。前缀和算法则是通过提前计算并存储这些前缀和&#xff0c;…

yum安装指定版本Redis

一&#xff0c;yum安装Redis 1&#xff0c;列出可用的redis版本 yum --showduplicates list redis 只有5.0.3.5版本&#xff0c;如果已经满足需求&#xff0c;可以直接安装 2&#xff0c;安装redis yum -y install 如果显示installed&#xff0c; 说明安装成功了 也可以通过…

DAY21|二叉树Part08|LeetCode: 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

目录 LeetCode: 669. 修剪二叉搜索树 基本思路 C代码 LeetCode: 108.将有序数组转换为二叉搜索树 基本思路 C代码 LeetCode: 538.把二叉搜索树转换为累加树 基本思路 C代码 LeetCode: 669. 修剪二叉搜索树 力扣代码链接 文字讲解&#xff1a;LeetCode: 669. 修剪二叉搜…

HarmonyOS基础:鸿蒙系统组件导航Navigation

大家好&#xff01;我是黑臂麒麟&#xff08;起名原因&#xff1a;一个出生全右臂自带纹身的高质量程序员&#x1f60f;&#xff09;&#xff0c;也是一位6&#xff08;约2个半坤年&#xff09;的前端&#xff1b; 学习如像练武功一样&#xff0c;理论和实践要相结合&#xff0…

​Houdini云渲染如何使用?如何让一个镜头使用成百上千台机器渲染,提高渲染效率

​Houdini云渲染如何使用&#xff1f;如何让一个镜头使用成百上千台机器渲染&#xff0c;提高渲染效率呢&#xff0c;最简单的教程来了&#xff01; 第一步&#xff1a;云渲码6666注册成都渲染101&#xff0c;并且下载渲染101客户端 客户端是上传下载的工具&#xff0c;将文件…

如何使用Varjo直接观看Blender内容

最近&#xff0c;开源的3D建模程序Blender为Varjo提供了出色的OpenXR支持&#xff0c;包括四视图和凹进渲染扩展。但是在Blender中&#xff0c;默认不启用VR场景检查。要开始使用VR场景检查&#xff0c;只需遵循以下步骤&#xff1a; 1. 下载并安装Blender 2.启用Blender VR场景…

linux 安装anaconda3

1.下载 使用repo镜像网址下载对应安装包 右击获取下载地址&#xff0c;使用终端下载 wget https://repo.anaconda.com/archive/Anaconda3-2024.02-1-Linux-x86_64.sh2.安装 使用以下命令可直接指定位置 bash Anaconda3-2024.02-1-Linux-x86_64.sh -b -p /home/anaconda3也…

JavaScript。—关于语法基础的理解—

一、程序控制语句 JavaScript 提供了 if 、if else 和 switch 3种条件语句&#xff0c;条件语句也可以嵌套。 &#xff08;一&#xff09;、条件语句 1、单向判断 &#xff1a; if... &#xff08;1&#xff09;概述 < if >元素用于在判断该语句是否满足特定条…

DDD学习笔记

DDD学习笔记 1. 什么是 DDD&#xff1f; 领域驱动设计&#xff08;Domain-Driven Design, DDD&#xff09;是一种复杂软件系统设计的方法&#xff0c;强调以业务领域为核心进行设计与开发。它通过将业务逻辑与代码组织紧密结合&#xff0c;帮助开发团队更好地理解和实现业务需…

c语言简单编程练习8

1、递归函数&#xff1a; 通过调用自身来解决问题的函数&#xff0c;递归也就是传递和回归&#xff1b; 递归函数的两个条件&#xff1a; 1&#xff09;函数调用函数本身 2&#xff09;一定要有结束条件 循环与递归的区别&#xff1a; 每调用一次递归函数&#xff0c;都会…

如何将MySQL彻底卸载干净

目录 背景&#xff1a; MySQL的卸载 步骤1&#xff1a;停止MySQL服务 步骤2&#xff1a;软件的卸载 步骤3&#xff1a;残余文件的清理 步骤4&#xff1a;清理注册表 步骤五:删除环境变量配置 总结&#xff1a; 背景&#xff1a; MySQL卸载不彻底往往会导致重新安装失败…

linux-环境变量

环境变量是系统提供的一组 name value 的变量&#xff0c;不同的变量有不同的用途&#xff0c;通常都具有全局属性 env 查看环境变量 PATH PATH是一个保存着系统指令路径的一个环境变量&#xff0c;系统提供的指令不需要路径&#xff0c;直接就可以使用就是因为指令的路径…