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);
}
}
}
```
推荐阅读
-
本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ...
[详细]
蜡笔小新 2024-12-27 13:55:14
-
本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ...
[详细]
蜡笔小新 2024-12-27 10:18:13
-
-
本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ...
[详细]
蜡笔小新 2024-12-26 19:26:18
-
本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ...
[详细]
蜡笔小新 2024-12-28 12:07:46
-
本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ...
[详细]
蜡笔小新 2024-12-28 11:15:04
-
本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ...
[详细]
蜡笔小新 2024-12-28 09:46:23
-
本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ...
[详细]
蜡笔小新 2024-12-27 19:10:10
-
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
-
本文探讨了机器学习中常见的相似度度量方法,包括余弦相似度、欧氏距离和马氏距离,并详细介绍了如何通过选择合适的模型复杂度和正则化来提高模型的泛化能力。此外,文章还涵盖了模型评估的各种方法和指标,以及不同分类器的工作原理和应用场景。 ...
[详细]
蜡笔小新 2024-12-26 18:10:02
-
本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ...
[详细]
蜡笔小新 2024-12-28 09:35:00
-
本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ...
[详细]
蜡笔小新 2024-12-28 08:44:35
-
探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ...
[详细]
蜡笔小新 2024-12-27 14:34:44
-
本文详细介绍了机器学习中广泛应用的决策树算法,通过天气数据集的实例演示了ID3和CART算法的手动推导过程。文章长度约2000字,建议阅读时间5分钟。 ...
[详细]
蜡笔小新 2024-12-27 13:44:59
-
在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ...
[详细]
蜡笔小新 2024-12-27 12:39:06
-
本文探讨了卷积神经网络(CNN)中感受野的概念及其与锚框(anchor box)的关系。感受野定义了特征图上每个像素点对应的输入图像区域大小,而锚框则是在每个像素中心生成的多个不同尺寸和宽高比的边界框。两者在目标检测任务中起到关键作用。 ...
[详细]
蜡笔小新 2024-12-27 12:03:44
-
致力于流浪动物救助量
这个家伙很懒,什么也没留下!