写这个的目的是为了,加深对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();
}
}
}