写这个的目的是为了,加深对MMatrix33作用,有什么用的理解;
当然,里面的运算,为什么这写法,算法,我都是抄了别的语言过来的;
以下部份运算,是参考了:AS3 Starling ,与网络上其它相关矩阵信息的运算方式;
最终我的目的是,为了能先加深对矩阵运算理解;再看看Cocos2d-xna(WP7)版的源码(虽然官方是因为Win8已出,而已停止扩展);
然后最终再自己写一个轻量级的:3D渲染,的2D简单框架;
源码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; namespace Base.MyMath { /// <summary> /// 3 * 3 矩阵 /// Author : Jave.Lin /// Date : 2013-08-30 /// </summary> public struct MMatrix33 { /* * [m11, m12, m13] * [m21, m22, m23] * [m31, m32, m33] * */ public float m11, m12, m13; public float m21, m22, m23; public float m31, m32, m33; /** * ================> * (1)、缩放:s * [m11 * s, m12 * s, 0] * [m21 * s, m22 * s, 0] * [0, 0, 1] * * ================> * (2)、位移:x, y * [1, 0, 0] * [0, 1, 0] == tm * [x, y, 1] * sm = sm * tm//sm:源矩阵;tm:位移矩阵 * * ================> * (3)、旋转:r * [cos(r), sin(r), 0] * [-sin(r), cos(r), 0] == rm * [0, 0, 1] * sm = sm * tm//sm:源矩阵;rm:旋转矩阵 * * ================> * (4)、扭曲:skewX, skewY * [m11, m12, m13] [a, b, 0] * [m21, m22, m23] ==> [c, d, 0] * [m31, m32, m33] [tx,ty,1] * float sinX = (float)Math.Sin(skewX); * float cosX = (float)Math.Cos(skewX); * float sinY = (float)Math.Sin(skewY); * float cosY = (float)Math.Cos(skewY); * a = a * cosY - b * sinX;//a * b = a * sinY + b * cosX;//b * c = c * cosY - d * sinX;//c * d = c * sinY + d * cosX;//d * tx = tx * cosY - ty * sinX;//tx * ty = tx * sinY + ty * cosX;//ty * */ public MMatrix33() { m11 = m22 = m33 = 1; m12 = m13 = m21 = m23 = m31 = m32 = 0; } //临时矩阵池 private static Queue<MMatrix33> mPool = new Queue<MMatrix33>(); //获取临时矩阵(出队) private static MMatrix33 getM() { return mPool.Count > 0 ? mPool.Dequeue() : new MMatrix33(); } //回收临时矩阵(入队) private static void pushM(MMatrix33 m) { m.identity(); mPool.Enqueue(m); } /// <summary> /// 单位化 /// </summary> public void identity() { MMatrix33.identity(ref this); } /// <summary> /// 旋转 /// </summary> /// <param name="rotation"></param> public void rotate(float rotation) { MMatrix33.rotate(ref this, rotation); } /// <summary> /// 根据方向旋转 /// </summary> /// <param name="fwd"></param> /// <param name="side"></param> public void rotateByV(Vector2 fwd, Vector2 side) { MMatrix33.rotateByV(ref this, fwd, side); } /// <summary> /// 矩阵相乘 /// </summary> /// <param name="m"></param> public void mul(MMatrix33 m) { MMatrix33.mul(ref this, m); } /// <summary> /// 位移 /// </summary> /// <param name="v"></param> public void translate(Vector2 v) { MMatrix33.translate(ref this, v); } /// <summary> /// 缩放 /// </summary> /// <param name="s"></param> public void scale(float s) { MMatrix33.scale(ref this, s); } /// <summary> /// 根据水平、垂直缩放 /// </summary> /// <param name="scaleX"></param> /// <param name="scaleY"></param> public void scaleXY(float scaleX, float scaleY) { MMatrix33.scaleXY(ref this, scaleX, scaleY); } /// <summary> /// 根据指定的Vector2向量缩放 /// </summary> /// <param name="v"></param> public void scaleByV(Vector2 v) { MMatrix33.scaleByV(ref this, v); } /// <summary> /// 扭曲 /// </summary> /// <param name="skewX"></param> /// <param name="skewY"></param> public void skew(float skewX, float skewY) { MMatrix33.skew(ref this, skewX, skewY); } /// <summary> /// 复制 /// </summary> /// <returns></returns> public MMatrix33 copy() { return MMatrix33.copy(this); } /// <summary> /// 将所有指定的Vecotr2向量都应用指定的matrix坐标转换 /// </summary> /// <param name="matrix"></param> /// <param name="vecArr"></param> public static void transformVector2Arr(MMatrix33 matrix, ref Vector2[] vecArr) { for (int i = 0; i < vecArr.Length; i++) { transformVector2(matrix, ref vecArr[i]); } } /// <summary> /// 将指定的Vector2向量都应用指定的matrix坐标转换 /// </summary> /// <param name="matrix"></param> /// <param name="v"></param> 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; } /// <summary> /// 单位化矩阵 /// </summary> /// <param name="matrix"></param> 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; } /// <summary> /// 旋转矩阵 /// </summary> /// <param name="matrix"></param> /// <param name="rotation"></param> 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.mul(ref matrix, m); MMatrix33.pushM(m); } /// <summary> /// 根据指定的相前的向量fwd,指定的法向量side,旋转矩阵 /// </summary> /// <param name="matrix"></param> /// <param name="fwd"></param> /// <param name="side"></param> 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.mul(ref matrix, m); MMatrix33.pushM(m); } /// <summary> /// 矩阵相乘 /// </summary> /// <param name="matrix"></param> /// <param name="m"></param> public static void mul(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; } /// <summary> /// 矩阵根据指定量的Vector2向量位移 /// </summary> /// <param name="matrix"></param> /// <param name="v"></param> 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.mul(ref matrix, m); } /// <summary> /// 缩放矩阵 /// </summary> /// <param name="matrix"></param> /// <param name="scale"></param> public static void scale(ref MMatrix33 matrix, float scale) { MMatrix33.scaleXY(ref matrix, scale, scale); } /// <summary> /// 根据指定的水平、垂直缩放 /// </summary> /// <param name="matrix"></param> /// <param name="scaleX"></param> /// <param name="scaleY"></param> public static void scaleXY(ref MMatrix33 matrix, float scaleX, float scaleY) { matrix.m11 *= scaleX; matrix.m12 *= scaleX; matrix.m21 *= scaleY; matrix.m22 *= scaleY; } /// <summary> /// 根据指定的向量,缩放矩阵 /// </summary> /// <param name="matrix"></param> /// <param name="v"></param> public static void scaleByV(ref MMatrix33 matrix, Vector2 v) { MMatrix33.scaleXY(ref matrix, v.X, v.Y); } /// <summary> /// 扭曲 /// </summary> /// <param name="matrix"></param> /// <param name="skewX"></param> /// <param name="skewY"></param> 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); //MMatrix33 /* * [a, b, 0] * [c, d, 0] * [tx, ty, 1] * */ //相当于flash的a,c,b,d,tx,ty /* * [a, b, tx] * [c, d, ty] * [0, 0, 1] * */ matrix.m11 = matrix.m11 * cosY - matrix.m12 * sinX;//a matrix.m12 = matrix.m11 * sinY + matrix.m12 * cosX;//b matrix.m21 = matrix.m21 * cosY - matrix.m22 * sinX;//c matrix.m22 = matrix.m21 * sinY + matrix.m22 * cosX;//d matrix.m31 = matrix.m31 * cosY - matrix.m32 * sinX;//tx matrix.m32 = matrix.m31 * sinY + matrix.m32 * cosX;//ty } /// <summary> /// 复制对象 /// </summary> /// <param name="m"></param> /// <returns></returns> public static MMatrix33 copy(MMatrix33 m) { return (MMatrix33)m.MemberwiseClone(); } } }