Pagelist |
Last changed on Wednesday, 28th July; at 6:46pm (UTC+1) MatricesMatrices are really annoying me right now; I don't really understand them, and they're necessary for 3-dimensional game programming in XNA, a library for Direct X. I can use the built-in matrix class (just), but I felt I needed something more intuitive, so this is what I came up with:using System;
using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Storage; namespace MyMatrix { class MyMatrix { #region Private variables float[,] mMatrix; Vector3 mRot; Vector3 mScale; float fScale; #endregion /// /// Constructor for the MyMatrix class. /// public MyMatrix() { mMatrix = new float[4, 4]; mRot = mScale = new Vector3(0, 0, 0); fScale = 0.0f; } #region Transformations /// /// Creates a rotation around all three axes. /// public Vector3 Rotation { get {return mRot;} set { float[,] XMat = new float[4, 4]; float[,] YMat = new float[4, 4]; float[,] ZMat = new float[4, 4]; //The first expression in each mini-block ensures that the scale stays as 1 for the purposes of the rotation. XMat[0, 0] = 1; XMat[1, 1] = (float) Math.Cos(MathHelper.ToRadians(value.X)); XMat[1, 2] = (float) Math.Sin(MathHelper.ToRadians(value.X)); XMat[2, 1] = (float)-Math.Sin(MathHelper.ToRadians(value.X)); XMat[2, 2] = (float) Math.Cos(MathHelper.ToRadians(value.X)); YMat[1, 1] = 1; YMat[0, 0] = (float) Math.Cos(MathHelper.ToRadians(value.Y)); YMat[0, 2] = (float) Math.Sin(MathHelper.ToRadians(value.Y)); YMat[2, 0] = (float)-Math.Sin(MathHelper.ToRadians(value.Y)); YMat[2, 2] = (float) Math.Cos(MathHelper.ToRadians(value.Y)); ZMat[2, 2] = 1; ZMat[0, 0] = (float) Math.Cos(MathHelper.ToRadians(value.Z)); ZMat[0, 1] = (float) Math.Sin(MathHelper.ToRadians(value.Z)); ZMat[1, 0] = (float)-Math.Sin(MathHelper.ToRadians(value.Z)); ZMat[1, 1] = (float) Math.Cos(MathHelper.ToRadians(value.Z)); #region mMatrix += XMat*YMat*ZMat; mMatrix[0, 0] += XMat[0, 0] * YMat[0, 0] * ZMat[0, 0]; mMatrix[0, 1] += XMat[0, 1] * YMat[0, 1] * ZMat[0, 1]; mMatrix[0, 2] += XMat[0, 2] * YMat[0, 2] * ZMat[0, 2]; mMatrix[1, 0] += XMat[1, 0] * YMat[1, 0] * ZMat[1, 0]; mMatrix[1, 1] += XMat[1, 1] * YMat[1, 1] * ZMat[1, 1]; mMatrix[1, 2] += XMat[1, 2] * YMat[1, 2] * ZMat[1, 2]; mMatrix[2, 0] += XMat[2, 0] * YMat[2, 0] * ZMat[2, 0]; mMatrix[2, 1] += XMat[2, 1] * YMat[2, 1] * ZMat[2, 1]; mMatrix[2, 2] += XMat[2, 2] * YMat[2, 2] * ZMat[2, 2]; #endregion mRot = value; } } /// /// Scales points relative to 0,0 on the grid using a vector /// public Vector3 Scale { get { return mScale; } set { mMatrix[0, 0] *= value.X; mMatrix[1, 1] *= value.Y; mMatrix[2, 2] *= value.Z; } } /// /// Scales in all directions by a certain amount. /// public float FScale { get { return fScale; } set { mMatrix[3, 3] = value; fScale = value; } } /// /// Moves the point by a certain amount in each direction, specified with a vector /// public Vector3 Translate { set { mMatrix[0, 3] += value.X; mMatrix[1, 3] += value.Y; mMatrix[2, 3] += value.Z; } } #endregion #region Operators used to apply the matrix to a Vector3 static public Vector3 operator *(MyMatrix op1, Vector3 op2) { Vector3 tempVector; tempVector.X = ((op1.mMatrix[0, 0] * op2.X) + (op1.mMatrix[0, 1] * op2.Y) + (op1.mMatrix[0, 0] * op2.Z) + op1.mMatrix[0, 3]) / op1.mMatrix[3, 3]; tempVector.Y = ((op1.mMatrix[1, 0] * op2.X) + (op1.mMatrix[1, 1] * op2.Y) + (op1.mMatrix[1, 0] * op2.Z) + op1.mMatrix[1, 3]) / op1.mMatrix[3, 3]; tempVector.Z = ((op1.mMatrix[2, 0] * op2.X) + (op1.mMatrix[2, 1] * op2.Y) + (op1.mMatrix[2, 0] * op2.Z) + op1.mMatrix[2, 3]) / op1.mMatrix[3, 3]; return tempVector; } static public Vector3 operator *(Vector3 op1, MyMatrix op2) { Vector3 tempVector; tempVector.X = ((op2.mMatrix[0, 0] * op1.X) + (op2.mMatrix[0, 1] * op1.Y) + (op2.mMatrix[0, 0] * op1.Z) + op2.mMatrix[0, 3]) / op2.mMatrix[3, 3]; tempVector.Y = ((op2.mMatrix[1, 0] * op1.X) + (op2.mMatrix[1, 1] * op1.Y) + (op2.mMatrix[1, 0] * op1.Z) + op2.mMatrix[1, 3]) / op2.mMatrix[3, 3]; tempVector.Z = ((op2.mMatrix[2, 0] * op1.X) + (op2.mMatrix[2, 1] * op1.Y) + (op2.mMatrix[2, 0] * op1.Z) + op2.mMatrix[2, 3]) / op2.mMatrix[3, 3]; return tempVector; } #endregion #region Basic math operators for MyMatrix static public MyMatrix operator +(MyMatrix op1, MyMatrix op2) { MyMatrix TempMatrix; #region TempMatrix.mMatrix = op1.mMatrix + op2.mMatrix; TempMatrix.mMatrix[0, 0] = op1.mMatrix[0, 0] + op2.mMatrix[0, 0]; TempMatrix.mMatrix[0, 1] = op1.mMatrix[0, 1] + op2.mMatrix[0, 1]; TempMatrix.mMatrix[0, 2] = op1.mMatrix[0, 2] + op2.mMatrix[0, 2]; TempMatrix.mMatrix[0, 3] = op1.mMatrix[0, 3] + op2.mMatrix[0, 3]; TempMatrix.mMatrix[1, 0] = op1.mMatrix[1, 0] + op2.mMatrix[1, 0]; TempMatrix.mMatrix[1, 1] = op1.mMatrix[1, 1] + op2.mMatrix[1, 1]; TempMatrix.mMatrix[1, 2] = op1.mMatrix[1, 2] + op2.mMatrix[1, 2]; TempMatrix.mMatrix[1, 3] = op1.mMatrix[1, 3] + op2.mMatrix[1, 3]; TempMatrix.mMatrix[2, 0] = op1.mMatrix[2, 0] + op2.mMatrix[2, 0]; TempMatrix.mMatrix[2, 1] = op1.mMatrix[2, 1] + op2.mMatrix[2, 1]; TempMatrix.mMatrix[2, 2] = op1.mMatrix[2, 2] + op2.mMatrix[2, 2]; TempMatrix.mMatrix[2, 3] = op1.mMatrix[2, 3] + op2.mMatrix[2, 3]; #endregion return TempMatrix; } static public MyMatrix operator -(MyMatrix op1, MyMatrix op2) { MyMatrix TempMatrix; #region TempMatrix.mMatrix = op1.mMatrix - op2.mMatrix; TempMatrix.mMatrix[0, 0] = op1.mMatrix[0, 0] - op2.mMatrix[0, 0]; TempMatrix.mMatrix[0, 1] = op1.mMatrix[0, 1] - op2.mMatrix[0, 1]; TempMatrix.mMatrix[0, 2] = op1.mMatrix[0, 2] - op2.mMatrix[0, 2]; TempMatrix.mMatrix[0, 3] = op1.mMatrix[0, 3] - op2.mMatrix[0, 3]; TempMatrix.mMatrix[1, 0] = op1.mMatrix[1, 0] - op2.mMatrix[1, 0]; TempMatrix.mMatrix[1, 1] = op1.mMatrix[1, 1] - op2.mMatrix[1, 1]; TempMatrix.mMatrix[1, 2] = op1.mMatrix[1, 2] - op2.mMatrix[1, 2]; TempMatrix.mMatrix[1, 3] = op1.mMatrix[1, 3] - op2.mMatrix[1, 3]; TempMatrix.mMatrix[2, 0] = op1.mMatrix[2, 0] - op2.mMatrix[2, 0]; TempMatrix.mMatrix[2, 1] = op1.mMatrix[2, 1] - op2.mMatrix[2, 1]; TempMatrix.mMatrix[2, 2] = op1.mMatrix[2, 2] - op2.mMatrix[2, 2]; TempMatrix.mMatrix[2, 3] = op1.mMatrix[2, 3] - op2.mMatrix[2, 3]; #endregion return TempMatrix; } static public MyMatrix operator *(MyMatrix op1, MyMatrix op2) { MyMatrix TempMatrix; #region TempMatrix.mMatrix = op1.mMatrix * op2.mMatrix; TempMatrix.mMatrix[0, 0] = op1.mMatrix[0, 0] * op2.mMatrix[0, 0]; TempMatrix.mMatrix[0, 1] = op1.mMatrix[0, 1] * op2.mMatrix[0, 1]; TempMatrix.mMatrix[0, 2] = op1.mMatrix[0, 2] * op2.mMatrix[0, 2]; TempMatrix.mMatrix[0, 3] = op1.mMatrix[0, 3] * op2.mMatrix[0, 3]; TempMatrix.mMatrix[1, 0] = op1.mMatrix[1, 0] * op2.mMatrix[1, 0]; TempMatrix.mMatrix[1, 1] = op1.mMatrix[1, 1] * op2.mMatrix[1, 1]; TempMatrix.mMatrix[1, 2] = op1.mMatrix[1, 2] * op2.mMatrix[1, 2]; TempMatrix.mMatrix[1, 3] = op1.mMatrix[1, 3] * op2.mMatrix[1, 3]; TempMatrix.mMatrix[2, 0] = op1.mMatrix[2, 0] * op2.mMatrix[2, 0]; TempMatrix.mMatrix[2, 1] = op1.mMatrix[2, 1] * op2.mMatrix[2, 1]; TempMatrix.mMatrix[2, 2] = op1.mMatrix[2, 2] * op2.mMatrix[2, 2]; TempMatrix.mMatrix[2, 3] = op1.mMatrix[2, 3] * op2.mMatrix[2, 3]; #endregion return TempMatrix; } static public MyMatrix operator /(MyMatrix op1, MyMatrix op2) { MyMatrix TempMatrix; #region TempMatrix.mMatrix = op1.mMatrix / op2.mMatrix; TempMatrix.mMatrix[0, 0] = op1.mMatrix[0, 0] / op2.mMatrix[0, 0]; TempMatrix.mMatrix[0, 1] = op1.mMatrix[0, 1] / op2.mMatrix[0, 1]; TempMatrix.mMatrix[0, 2] = op1.mMatrix[0, 2] / op2.mMatrix[0, 2]; TempMatrix.mMatrix[0, 3] = op1.mMatrix[0, 3] / op2.mMatrix[0, 3]; TempMatrix.mMatrix[1, 0] = op1.mMatrix[1, 0] / op2.mMatrix[1, 0]; TempMatrix.mMatrix[1, 1] = op1.mMatrix[1, 1] / op2.mMatrix[1, 1]; TempMatrix.mMatrix[1, 2] = op1.mMatrix[1, 2] / op2.mMatrix[1, 2]; TempMatrix.mMatrix[1, 3] = op1.mMatrix[1, 3] / op2.mMatrix[1, 3]; TempMatrix.mMatrix[2, 0] = op1.mMatrix[2, 0] / op2.mMatrix[2, 0]; TempMatrix.mMatrix[2, 1] = op1.mMatrix[2, 1] / op2.mMatrix[2, 1]; TempMatrix.mMatrix[2, 2] = op1.mMatrix[2, 2] / op2.mMatrix[2, 2]; TempMatrix.mMatrix[2, 3] = op1.mMatrix[2, 3] / op2.mMatrix[2, 3]; #endregion return TempMatrix; } #endregion } } |
Tags |