热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#XNA中实现自定义3x3矩阵类:MMatrix33

本文介绍了如何在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在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • 本文详细介绍了装饰者(Decorator)模式,这是一种动态地为对象添加职责的方法。与传统的继承方式不同,装饰者模式通过组合而非继承来实现功能扩展,从而提供更大的灵活性和可维护性。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 深入解析Java多线程与并发库的应用:空中网实习生面试题详解
    本文详细探讨了Java多线程与并发库的高级应用,结合空中网在挑选实习生时的面试题目,深入分析了相关技术要点和实现细节。文章通过具体的代码示例展示了如何使用Semaphore和SynchronousQueue来管理线程同步和任务调度。 ... [详细]
  • 软件工程课堂测试2
    要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 本文深入探讨了 Delphi 中类对象成员的核心概念,包括 System 单元的基础知识、TObject 类的定义及其方法、TClass 的作用以及对象的消息处理机制。文章不仅解释了这些概念的基本原理,还提供了丰富的补充和专业解答,帮助读者全面理解 Delphi 的面向对象编程。 ... [详细]
  • 本文探讨了如何使用pg-promise库在PostgreSQL中高效地批量插入多条记录,包括通过事务和单一查询两种方法。 ... [详细]
author-avatar
致力于流浪动物救助量
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有