C#XNA中实现自定义3x3矩阵类:MMatrix33
作者:致力于流浪动物救助量 | 来源:互联网 | 2024-12-21 17:27
本文介绍了如何在C#和XNA框架中实现一个自定义的3x3矩阵类(MMatrix33),旨在深入理解矩阵运算及其应用场景。该类参考了AS3Starling和其他相关资源,以确保算法的准确性和高效性。
为了更好地理解和应用 3x3 矩阵的运算,本文详细描述了 MMatrix33 类的实现过程。通过借鉴 AS3 Starling 和网络上的相关资源,我们实现了多种矩阵操作,如缩放、位移、旋转和扭曲等。
最终目标是通过深入研究矩阵运算,进一步探索 Cocos2d-xna(WP7)版源码,并最终构建一个轻量级的 2D 渲染框架。
以下是 MMatrix33 类的完整代码实现:
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
namespace Base.MyMath
{
///
/// 3x3 矩阵类
/// Author: Jave.Lin
/// Date: 2013-08-30
///
public struct MMatrix33
{
// 矩阵元素
public float m11, m12, m13;
public float m21, m22, m23;
public float m31, m32, m33;
// 构造函数
public MMatrix33()
{
m11 = m22 = m33 = 1;
m12 = m13 = m21 = m23 = m31 = m32 = 0;
}
// 单位化矩阵
public void Identity()
{
MMatrix33.Identity(ref this);
}
// 旋转矩阵
public void Rotate(float rotation)
{
MMatrix33.Rotate(ref this, rotation);
}
// 根据方向旋转矩阵
public void RotateByV(Vector2 fwd, Vector2 side)
{
MMatrix33.RotateByV(ref this, fwd, side);
}
// 矩阵相乘
public void Multiply(MMatrix33 m)
{
MMatrix33.Multiply(ref this, m);
}
// 位移矩阵
public void Translate(Vector2 v)
{
MMatrix33.Translate(ref this, v);
}
// 缩放矩阵
public void Scale(float s)
{
MMatrix33.Scale(ref this, s);
}
// 根据水平、垂直缩放
public void ScaleXY(float scaleX, float scaleY)
{
MMatrix33.ScaleXY(ref this, scaleX, scaleY);
}
// 根据指定的向量缩放
public void ScaleByV(Vector2 v)
{
MMatrix33.ScaleByV(ref this, v);
}
// 扭曲矩阵
public void Skew(float skewX, float skewY)
{
MMatrix33.Skew(ref this, skewX, skewY);
}
// 复制矩阵
public MMatrix33 Copy()
{
return MMatrix33.Copy(this);
}
// 将所有指定的Vector2向量都应用指定的matrix坐标转换
public static void TransformVector2Arr(MMatrix33 matrix, ref Vector2[] vecArr)
{
for (int i = 0; i {
TransformVector2(matrix, ref vecArr[i]);
}
}
// 将指定的Vector2向量应用指定的matrix坐标转换
public static void TransformVector2(MMatrix33 matrix, ref Vector2 v)
{
v.X = matrix.m11 * v.X + matrix.m21 * v.Y + matrix.m31;
v.Y = matrix.m12 * v.X + matrix.m22 * v.Y + matrix.m32;
}
// 单位化矩阵
public static void Identity(ref MMatrix33 matrix)
{
matrix.m11 = 1; matrix.m12 = 0; matrix.m13 = 0;
matrix.m21 = 0; matrix.m22 = 1; matrix.m23 = 0;
matrix.m31 = 0; matrix.m32 = 0; matrix.m33 = 1;
}
// 旋转矩阵
public static void Rotate(ref MMatrix33 matrix, float rotation)
{
MMatrix33 m = getM();
float sin = (float)Math.Sin(rotation);
float cos = (float)Math.Cos(rotation);
m.m11 = cos; m.m12 = sin; m.m13 = 0;
m.m21 = -sin; m.m22 = cos; m.m23 = 0;
m.m32 = 0; m.m32 = 0; m.m33 = 1;
MMatrix33.Multiply(ref matrix, m);
MMatrix33.PushM(m);
}
// 根据指定的方向向量旋转矩阵
public static void RotateByV(ref MMatrix33 matrix, Vector2 fwd, Vector2 side)
{
MMatrix33 m = getM();
m.m11 = fwd.X; m.m12 = fwd.Y; m.m13 = 0;
m.m21 = side.X; m.m22 = side.Y; m.m23 = 0;
m.m32 = 0; m.m32 = 0; m.m33 = 1;
MMatrix33.Multiply(ref matrix, m);
MMatrix33.PushM(m);
}
// 矩阵相乘
public static void Multiply(ref MMatrix33 matrix, MMatrix33 m)
{
// 第一行
matrix.m11 = matrix.m11 * m.m11 + matrix.m12 * m.m21 + matrix.m13 * m.m31;
matrix.m12 = matrix.m11 * m.m12 + matrix.m12 * m.m22 + matrix.m13 * m.m32;
matrix.m13 = matrix.m11 * m.m13 + matrix.m12 * m.m23 + matrix.m13 * m.m33;
// 第二行
matrix.m21 = matrix.m21 * m.m11 + matrix.m22 * m.m21 + matrix.m23 * m.m31;
matrix.m22 = matrix.m21 * m.m12 + matrix.m22 * m.m22 + matrix.m23 * m.m32;
matrix.m23 = matrix.m21 * m.m13 + matrix.m22 * m.m23 + matrix.m23 * m.m33;
// 第三行
matrix.m31 = matrix.m31 * m.m11 + matrix.m32 * m.m21 + matrix.m33 * m.m31;
matrix.m32 = matrix.m31 * m.m12 + matrix.m32 * m.m22 + matrix.m33 * m.m32;
matrix.m33 = matrix.m31 * m.m13 + matrix.m32 * m.m23 + matrix.m33 * m.m33;
}
// 矩阵根据指定量的Vector2向量位移
public static void Translate(ref MMatrix33 matrix, Vector2 v)
{
MMatrix33 m = getM();
m.m11 = 1; m.m12 = 0; m.m13 = 0;
m.m21 = 0; m.m22 = 1; m.m23 = 0;
m.m32 = v.X; m.m32 = v.Y; m.m33 = 1;
MMatrix33.Multiply(ref matrix, m);
}
// 缩放矩阵
public static void Scale(ref MMatrix33 matrix, float scale)
{
MMatrix33.ScaleXY(ref matrix, scale, scale);
}
// 根据指定的水平、垂直缩放
public static void ScaleXY(ref MMatrix33 matrix, float scaleX, float scaleY)
{
matrix.m11 *= scaleX; matrix.m12 *= scaleX;
matrix.m21 *= scaleY; matrix.m22 *= scaleY;
}
// 根据指定的向量缩放
public static void ScaleByV(ref MMatrix33 matrix, Vector2 v)
{
MMatrix33.ScaleXY(ref matrix, v.X, v.Y);
}
// 扭曲矩阵
public static void Skew(ref MMatrix33 matrix, float skewX, float skewY)
{
float sinX = (float)Math.Sin(skewX);
float cosX = (float)Math.Cos(skewX);
float sinY = (float)Math.Sin(skewY);
float cosY = (float)Math.Cos(skewY);
matrix.m11 = matrix.m11 * cosY - matrix.m12 * sinX;
matrix.m12 = matrix.m11 * sinY + matrix.m12 * cosX;
matrix.m21 = matrix.m21 * cosY - matrix.m22 * sinX;
matrix.m22 = matrix.m21 * sinY + matrix.m22 * cosX;
matrix.m31 = matrix.m31 * cosY - matrix.m32 * sinX;
matrix.m32 = matrix.m31 * sinY + matrix.m32 * cosX;
}
// 复制对象
public static MMatrix33 Copy(MMatrix33 m)
{
return (MMatrix33)m.MemberwiseClone();
}
// 临时矩阵池
private static Queue mPool = new Queue();
// 获取临时矩阵(出队)
private static MMatrix33 getM()
{
return mPool.Count > 0 ? mPool.Dequeue() : new MMatrix33();
}
// 回收临时矩阵(入队)
private static void PushM(MMatrix33 m)
{
m.Identity();
mPool.Enqueue(m);
}
}
}
```
推荐阅读
-
探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ...
[详细]
蜡笔小新 2024-12-21 10:13:36
-
本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ...
[详细]
蜡笔小新 2024-12-21 18:50:52
-
-
本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ...
[详细]
蜡笔小新 2024-12-21 17:33:44
-
本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ...
[详细]
蜡笔小新 2024-12-21 11:11:40
-
先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ...
[详细]
蜡笔小新 2024-12-20 18:17:25
-
本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ...
[详细]
蜡笔小新 2024-12-20 15:34:31
-
本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ...
[详细]
蜡笔小新 2024-12-20 12:58:21
-
本文详细介绍了装饰者(Decorator)模式,这是一种动态地为对象添加职责的方法。与传统的继承方式不同,装饰者模式通过组合而非继承来实现功能扩展,从而提供更大的灵活性和可维护性。 ...
[详细]
蜡笔小新 2024-12-21 13:38:07
-
Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ...
[详细]
蜡笔小新 2024-12-21 12:39:07
-
本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ...
[详细]
蜡笔小新 2024-12-21 10:29:05
-
本文详细探讨了Java多线程与并发库的高级应用,结合空中网在挑选实习生时的面试题目,深入分析了相关技术要点和实现细节。文章通过具体的代码示例展示了如何使用Semaphore和SynchronousQueue来管理线程同步和任务调度。 ...
[详细]
蜡笔小新 2024-12-21 09:43:07
-
要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ...
[详细]
蜡笔小新 2024-12-20 15:00:51
-
本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ...
[详细]
蜡笔小新 2024-12-20 10:14:51
-
本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ...
[详细]
蜡笔小新 2024-12-19 18:28:06
-
本文探讨了如何使用pg-promise库在PostgreSQL中高效地批量插入多条记录,包括通过事务和单一查询两种方法。 ...
[详细]
蜡笔小新 2024-12-19 12:55:22
-
致力于流浪动物救助量
这个家伙很懒,什么也没留下!