Click here to Skip to main content
15,895,777 members
Articles / Programming Languages / C#

Sharp3D.Math - A 3D math library for .NET

Rate me:
Please Sign up or sign in to vote.
4.30/5 (32 votes)
9 Jun 20041 min read 223.8K   6.6K   79  
A 3D math library written in C#
#region Sharp3D.Math, Copyright(C) 2003-2004 Eran Kampf, Licensed under LGPL.
//	Sharp3D.Math math library
//	Copyright (C) 2003-2004  
//	Eran Kampf
//	tentacle@zahav.net.il
//	http://tentacle.flipcode.com
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#endregion
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using System.Security.Permissions;
using System.Runtime.InteropServices;

namespace Sharp3D.Math.Core
{
	/// <summary>
	/// Represents a 3-dimentional single-precision floating point matrix class.
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(ExpandableObjectConverter))]
	[StructLayout(LayoutKind.Sequential)]
	public struct Matrix3F : ISerializable, ICloneable
	{
		#region Private Fields
		private float _m11, _m12, _m13;
		private float _m21, _m22, _m23;
		private float _m31, _m32, _m33;
		#endregion

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> structure with the specified values.
		/// </summary>
		public Matrix3F(
			float m11, float m12, float m13,
			float m21, float m22, float m23,
			float m31, float m32, float m33
			)
		{
			_m11 = m11; _m12 = m12; _m13 = m13;
			_m21 = m21; _m22 = m22; _m23 = m23;
			_m31 = m31; _m32 = m32; _m33 = m33;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> structure with the specified values.
		/// </summary>
		/// <param name="elements">An array containing the matrix values in row-major order.</param>
		public Matrix3F(float[] elements)
		{
			Debug.Assert(elements != null);
			Debug.Assert(elements.Length >= 9);

			_m11 = elements[0]; _m12 = elements[1]; _m13 = elements[2];
			_m21 = elements[3]; _m22 = elements[4]; _m23 = elements[5];
			_m31 = elements[6]; _m32 = elements[7]; _m33 = elements[7];
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> structure with the specified values.
		/// </summary>
		/// <param name="elements">An array containing the matrix values in row-major order.</param>
		public Matrix3F(FloatArrayList elements)
		{
			Debug.Assert(elements != null);
			Debug.Assert(elements.Count >= 9);

			_m11 = elements[0]; _m12 = elements[1]; _m13 = elements[2];
			_m21 = elements[3]; _m22 = elements[4]; _m23 = elements[5];
			_m31 = elements[6]; _m32 = elements[7]; _m33 = elements[7];
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> structure with the specified values.
		/// </summary>
		/// <param name="column1">A <see cref="Vector2D"/> instance holding values for the first column.</param>
		/// <param name="column2">A <see cref="Vector2D"/> instance holding values for the second column.</param>
		/// <param name="column3">A <see cref="Vector2D"/> instance holding values for the third column.</param>
		public Matrix3F(Vector3F column1, Vector3F column2, Vector3F column3)
		{
			_m11 = column1.X; _m12 = column2.X; _m13 = column3.X;
			_m21 = column1.Y; _m22 = column2.Y; _m23 = column3.Y;
			_m31 = column1.Z; _m32 = column2.Z; _m33 = column3.Z;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> class using a given matrix.
		/// </summary>
		public Matrix3F(Matrix3F m)
		{
			_m11 = m.M11; _m12 = m.M12; _m13 = m.M13;
			_m21 = m.M21; _m22 = m.M22; _m23 = m.M23;
			_m31 = m.M31; _m32 = m.M32; _m33 = m.M33;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Matrix3F"/> class with serialized data.
		/// </summary>
		/// <param name="info">The object that holds the serialized object data.</param>
		/// <param name="context">The contextual information about the source or destination.</param>
		private Matrix3F(SerializationInfo info, StreamingContext context)
		{
			// Get the first row
			_m11 = info.GetSingle("M11");
			_m12 = info.GetSingle("M12");
			_m13 = info.GetSingle("M13");

			// Get the second row
			_m21 = info.GetSingle("M21");
			_m22 = info.GetSingle("M22");
			_m23 = info.GetSingle("M23");

			// Get the third row
			_m31 = info.GetSingle("M31");
			_m32 = info.GetSingle("M32");
			_m33 = info.GetSingle("M33");
		}
		#endregion

		#region Constants
		/// <summary>
		/// 3-dimentional single-precision floating point zero matrix.
		/// </summary>
		public static readonly Matrix3F Zero = new Matrix3F(0,0,0,0,0,0,0,0,0);
		/// <summary>
		/// 3-dimentional single-precision floating point identity matrix.
		/// </summary>
		public static readonly Matrix3F Identity = new Matrix3F(
			1,0,0,
			0,1,0,
			0,0,1
			);
		#endregion

		#region ICloneable Members
		/// <summary>
		/// Creates an exact copy of this <see cref="Matrix3F"/> object.
		/// </summary>
		/// <returns>The <see cref="Matrix3F"/> object this method creates, cast as an object.</returns>
		object ICloneable.Clone()
		{
			return new Matrix3F(this);
		}
		/// <summary>
		/// Creates an exact copy of this <see cref="Matrix3F"/> object.
		/// </summary>
		/// <returns>The <see cref="Matrix3F"/> object this method creates.</returns>
		public Matrix3F Clone()
		{
			return new Matrix3F(this);
		}
		#endregion

		#region ISerializable Members
		/// <summary>
		/// Populates a <see cref="SerializationInfo"/> with the data needed to serialize this object.
		/// </summary>
		/// <param name="info">The <see cref="SerializationInfo"/> to populate with data. </param>
		/// <param name="context">The destination (see <see cref="StreamingContext"/>) for this serialization.</param>
		[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			// First row
			info.AddValue("M11", _m11);
			info.AddValue("M12", _m12);
			info.AddValue("M13", _m13);

			// Second row
			info.AddValue("M21", _m21);
			info.AddValue("M22", _m22);
			info.AddValue("M23", _m23);

			// Third row
			info.AddValue("M31", _m31);
			info.AddValue("M32", _m32);
			info.AddValue("M33", _m33);
		}
		#endregion

		#region Public Static Vector Arithmetics
		/// <summary>
		/// Adds two matrices.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the sum.</returns>
		public static Matrix3F Add(Matrix3F a, Matrix3F b)
		{
			return new Matrix3F(
				a.M11 + b.M11, a.M12 + b.M12, a.M13 + b.M13,
				a.M21 + b.M21, a.M22 + b.M22, a.M23 + b.M23,
				a.M31 + b.M31, a.M32 + b.M32, a.M33 + b.M33
				);
		}
		/// <summary>
		/// Adds a matrix and a scalar.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the sum.</returns>
		public static Matrix3F Add(Matrix3F a, float s)
		{
			return new Matrix3F(
				a.M11 + s, a.M12 + s, a.M13 + s, 
				a.M21 + s, a.M22 + s, a.M23 + s,
				a.M31 + s, a.M32 + s, a.M33 + s
				);
		}
		/// <summary>
		/// Adds two matrices and put the result in a third matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="result">A <see cref="Matrix3F"/> instance to hold the result.</param>
		public static void Add(Matrix3F a, Matrix3F b, Matrix3F result)
		{
			result.M11 = a.M11 + b.M11;
			result.M12 = a.M12 + b.M12;
			result.M13 = a.M13 + b.M13;

			result.M21 = a.M21 + b.M21;
			result.M22 = a.M22 + b.M22;
			result.M23 = a.M23 + b.M23;

			result.M31 = a.M31 + b.M31;
			result.M32 = a.M32 + b.M32;
			result.M33 = a.M33 + b.M33;
		}
		/// <summary>
		/// Adds a matrix and a scalar and put the result in a third matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <param name="result">A <see cref="Matrix3F"/> instance to hold the result.</param>
		public static void Add(Matrix3F a, float s, Matrix3F result)
		{
			result.M11 = a.M11 + s;
			result.M12 = a.M12 + s;
			result.M13 = a.M13 + s;

			result.M21 = a.M21 + s;
			result.M22 = a.M22 + s;
			result.M23 = a.M23 + s;

			result.M31 = a.M31 + s;
			result.M32 = a.M32 + s;
			result.M33 = a.M33 + s;
		}
		/// <summary>
		/// Subtracts a matrix from a matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the difference.</returns>
		public static Matrix3F Subtract(Matrix3F a, Matrix3F b)
		{
			return new Matrix3F(
				a.M11 - b.M11, a.M12 - b.M12, a.M13 - b.M13,
				a.M21 - b.M21, a.M22 - b.M22, a.M23 - b.M23,
				a.M31 - b.M31, a.M32 - b.M32, a.M33 - b.M33
				);
		}
		/// <summary>
		/// Subtracts a scalar from a matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the difference.</returns>
		public static Matrix3F Subtract(Matrix3F a, float s)
		{
			return new Matrix3F(
				a.M11 - s, a.M12 - s, a.M13 - s,
				a.M21 - s, a.M22 - s, a.M23 - s,
				a.M31 - s, a.M32 - s, a.M33 - s
				);
		}
		/// <summary>
		/// Subtracts a matrix from a matrix and put the result in a third matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="result">A <see cref="Matrix3F"/> instance to hold the result.</param>
		public static void Subtract(Matrix3F a, Matrix3F b, Matrix3F result)
		{
			result.M11 = a.M11 - b.M11;
			result.M12 = a.M12 - b.M12;
			result.M13 = a.M13 - b.M13;

			result.M21 = a.M21 - b.M21;
			result.M22 = a.M22 - b.M22;
			result.M23 = a.M23 - b.M23;

			result.M31 = a.M31 - b.M31;
			result.M32 = a.M32 - b.M32;
			result.M33 = a.M33 - b.M33;
		}
		/// <summary>
		/// Subtracts a scalar from a matrix and put the result in a third matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <param name="result">A <see cref="Matrix3F"/> instance to hold the result.</param>
		public static void Subtract(Matrix3F a, float s, Matrix3F result)
		{
			result.M11 = a.M11 - s;
			result.M12 = a.M12 - s;
			result.M13 = a.M13 - s;

			result.M21 = a.M21 - s;
			result.M22 = a.M22 - s;
			result.M23 = a.M23 - s;

			result.M31 = a.M31 - s;
			result.M32 = a.M32 - s;
			result.M33 = a.M33 - s;
		}
		/// <summary>
		/// Multiplies two matrices.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the result.</returns>
		public static Matrix3F Multiply(Matrix3F a, Matrix3F b)
		{
			return new Matrix3F(
				a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31,
				a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32,
				a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33,

				a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31,
				a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32,
				a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33,

				a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31,
				a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32, 
				a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33
				);
		}
		/// <summary>
		/// Multiplies two matrices and put the result in a third matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="result">A <see cref="Matrix3F"/> instance to hold the result.</param>
		public static void Multiply(Matrix3F a, Matrix3F b, Matrix3F result)
		{
			result.M11 = a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31;
			result.M12 = a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32;
			result.M13 = a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33;

			result.M21 = a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31;
			result.M22 = a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32;
			result.M23 = a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33;

			result.M31 = a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31;
			result.M32 = a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32; 
			result.M33 = a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33;
		}		
		/// <summary>
		/// Transforms a given vector by a matrix.
		/// </summary>
		/// <param name="matrix">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="vector">A <see cref="Vector3F"/> instance.</param>
		/// <returns>A new <see cref="Vector3F"/> instance containing the result.</returns>
		public static Vector3F Transform(Matrix3F matrix, Vector3F vector)
		{
			return new Vector3F(
				(matrix.M11 * vector.X) + (matrix.M12 * vector.Y) + (matrix.M13 * vector.Z),
				(matrix.M21 * vector.X) + (matrix.M22 * vector.Y) + (matrix.M23 * vector.Z),
				(matrix.M31 * vector.X) + (matrix.M32 * vector.Y) + (matrix.M33 * vector.Z));
		}
		/// <summary>
		/// Transforms a given vector by a matrix and put the result in a vector.
		/// </summary>
		/// <param name="matrix">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="vector">A <see cref="Vector3F"/> instance.</param>
		/// <param name="result">A <see cref="Vector3F"/> instance to hold the result.</param>
		public static void Transform(Matrix3F matrix, Vector3F vector, Vector3F result)
		{
			result.X = (matrix.M11 * vector.X) + (matrix.M12 * vector.Y) + (matrix.M13 * vector.Z);
			result.Y = (matrix.M21 * vector.X) + (matrix.M22 * vector.Y) + (matrix.M23 * vector.Z);
			result.Z = (matrix.M31 * vector.X) + (matrix.M32 * vector.Y) + (matrix.M33 * vector.Z);
		}
		/// <summary>
		/// Transposes a matrix.
		/// </summary>
		/// <param name="m">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the transposed matrix.</returns>
		public static Matrix3F Transpose(Matrix3F m)
		{
			Matrix3F t = new Matrix3F(m);
			t.Transpose();
			return t;
		}
		#endregion

		#region Public Properties
		/// <summary>
		/// Gets or sets the value of the [1,1] matrix element.
		/// </summary>
		public float M11
		{
			get { return _m11; }
			set { _m11 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [1,2] matrix element.
		/// </summary>
		public float M12
		{
			get { return _m12; }
			set { _m12 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [1,3] matrix element.
		/// </summary>
		public float M13
		{
			get { return _m13; }
			set { _m13 = value;}
		}


		/// <summary>
		/// Gets or sets the value of the [2,1] matrix element.
		/// </summary>
		public float M21
		{
			get { return _m21; }
			set { _m21 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [2,2] matrix element.
		/// </summary>
		public float M22
		{
			get { return _m22; }
			set { _m22 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [2,3] matrix element.
		/// </summary>
		public float M23
		{
			get { return _m23; }
			set { _m23 = value;}
		}


		/// <summary>
		/// Gets or sets the value of the [3,1] matrix element.
		/// </summary>
		public float M31
		{
			get { return _m31; }
			set { _m31 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [3,2] matrix element.
		/// </summary>
		public float M32
		{
			get { return _m32; }
			set { _m32 = value;}
		}
		/// <summary>
		/// Gets or sets the value of the [3,3] matrix element.
		/// </summary>
		public float M33
		{
			get { return _m33; }
			set { _m33 = value;}
		}
		#endregion

		#region Overrides
		/// <summary>
		/// Returns the hashcode for this instance.
		/// </summary>
		/// <returns>A 32-bit signed integer hash code.</returns>
		public override int GetHashCode()
		{
			return 
				_m11.GetHashCode() ^ _m12.GetHashCode() ^ _m13.GetHashCode() ^
				_m21.GetHashCode() ^ _m22.GetHashCode() ^ _m23.GetHashCode() ^
				_m31.GetHashCode() ^ _m32.GetHashCode() ^ _m33.GetHashCode();
		}
		/// <summary>
		/// Returns a value indicating whether this instance is equal to
		/// the specified object.
		/// </summary>
		/// <param name="obj">An object to compare to this instance.</param>
		/// <returns>True if <paramref name="obj"/> is a <see cref="Vector2D"/> and has the same values as this instance; otherwise, False.</returns>
		public override bool Equals(object obj)
		{
			if (obj is Matrix3F)
			{
				Matrix3F m = (Matrix3F)obj;
				return 
					(_m11 == m.M11) && (_m12 == m.M12) && (_m13 == m.M13) &&
					(_m21 == m.M21) && (_m22 == m.M22) && (_m23 == m.M23) &&
					(_m31 == m.M31) && (_m32 == m.M32) && (_m33 == m.M33);
			}
			return false;
		}

		/// <summary>
		/// Returns a string representation of this object.
		/// </summary>
		/// <returns>A string representation of this object.</returns>
		public override string ToString()
		{
			StringBuilder s = new StringBuilder();
			s.Append(String.Format( "|{0}, {1}, {3}|\n", _m11, _m12, _m13));
			s.Append(String.Format( "|{0}, {1}, {3}|\n", _m21, _m22, _m23));
			s.Append(String.Format( "|{0}, {1}, {3}|\n", _m31, _m32, _m33));

			return s.ToString();
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Calculates the determinant value of the matrix.
		/// </summary>
		/// <returns>The determinant value of the matrix.</returns>
		public float Determinant()
		{
			// rule of Sarrus
			return 
				_m11 * _m22 * _m33 + _m12 * _m23 * _m31 + _m13 * _m21 * _m32 -
				_m13 * _m22 * _m31 - _m11 * _m23 * _m32 - _m12 * _m21 * _m33;
		}
		/*
		/// <summary>
		/// Calculates the adjoint of the matrix.
		/// </summary>
		/// <returns>A <see cref="Matrix3F"/> instance containing the adjoint of the matrix.</returns>
		public Matrix3F Adjoint() 
		{
			Matrix3F result = new Matrix3F();
			for (int row = 0; row < 4; row++)
			{
				for (int col = 0; col < 4; col++) 
				{
					if (((col+row) % 2) == 0)
						result[row, col] = Minor(col, row).Determinant();
					else
						result[row, col] = -Minor(col, row).Determinant();
				}
			}

			return result;
		}
		/// <summary>
		/// Build a 3x3 matrix from from the current matrix without the given row and column.
		/// </summary>
		/// <param name="row">The row to remove.</param>
		/// <param name="column">The column to remove.</param>
		/// <returns>A <see cref="Matrix3F"/> instance containing the result Minor.</returns>
		public Matrix3F Minor(int row, int column) 
		{
			int r = 0;
			Matrix3F result = new Matrix3F();
			for (int row = 0; row < 4; row++) 
			{
				int c = 0;
				if (row != row) 
				{
					for (int column = 0; column < 4; column++) 
					{
						if (column != column) 
						{
							result[r,c] = this[row, column];
							c++;
						}
					}
					r++;
				}
			}
			return result;
		}
		*/

		/// <summary>
		/// Calculates the trace the matrix which is the sum of its diagonal elements.
		/// </summary>
		/// <returns>Returns the trace value of the matrix.</returns>
		public float Trace()
		{
			return _m11 + _m22 + _m33;
		}
		/// <summary>
		/// Transposes this matrix.
		/// </summary>
		public void Transpose()
		{
			MathFunctions.Swap(ref _m12, ref _m21);
			MathFunctions.Swap(ref _m13, ref _m31);
			MathFunctions.Swap(ref _m23, ref _m32);
		}
		#endregion

		#region Comparison Operators
		/// <summary>
		/// Tests whether two specified matrices are equal.
		/// </summary>
		/// <param name="a">The left-hand matrix.</param>
		/// <param name="b">The right-hand matrix.</param>
		/// <returns>True if the two matrices are equal; otherwise, False.</returns>
		public static bool operator==(Matrix3F a, Matrix3F b)
		{
			if(Object.Equals(a, null) == true) 
			{
				return Object.Equals(b, null);
			}
			
			if(Object.Equals(b, null) == true) 
			{
				return Object.Equals(a, null);
			}

			return 
				(a.M11 == b.M11) && (a.M12 == b.M12) && (a.M13 == b.M13) &&
				(a.M21 == b.M21) && (a.M22 == b.M22) && (a.M23 == b.M23) &&
				(a.M31 == b.M31) && (a.M32 == b.M32) && (a.M33 == b.M33);

		}
		/// <summary>
		/// Tests whether two specified matrices are not equal.
		/// </summary>
		/// <param name="a">The left-hand matrix.</param>
		/// <param name="b">The right-hand matrix.</param>
		/// <returns>True if the two matrices are not equal; otherwise, False.</returns>
		public static bool operator!=(Matrix3F a, Matrix3F b)
		{
			if(Object.Equals(a, null) == true) 
			{
				return !Object.Equals(b, null);
			}
			
			if(Object.Equals(b, null) == true) 
			{
				return !Object.Equals(a, null);
			}

			return !(
				(a.M11 == b.M11) && (a.M12 == b.M12) && (a.M13 == b.M13) &&
				(a.M21 == b.M21) && (a.M22 == b.M22) && (a.M23 == b.M23) &&
				(a.M31 == b.M31) && (a.M32 == b.M32) && (a.M33 == b.M33)
				);

		}
		#endregion

		#region Binary Operators
		/// <summary>
		/// Adds two matrices.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the sum.</returns>
		public static Matrix3F operator+(Matrix3F a, Matrix3F b)
		{
			return Matrix3F.Add(a,b);
		}
		/// <summary>
		/// Adds a matrix and a scalar.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the sum.</returns>
		public static Matrix3F operator+(Matrix3F a, float s)
		{
			return Matrix3F.Add(a,s);
		}
		/// <summary>
		/// Adds a matrix and a scalar.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the sum.</returns>
		public static Matrix3F operator+(float s, Matrix3F a)
		{
			return Matrix3F.Add(a,s);
		}
		/// <summary>
		/// Subtracts a matrix from a matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the difference.</returns>
		public static Matrix3F operator-(Matrix3F a, Matrix3F b)
		{
			return Matrix3F.Subtract(a,b);
		}
		/// <summary>
		/// Subtracts a scalar from a matrix.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="s">A scalar.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the difference.</returns>
		public static Matrix3F operator-(Matrix3F a, float s)
		{
			return Matrix3F.Subtract(a,s);
		}
		/// <summary>
		/// Multiplies two matrices.
		/// </summary>
		/// <param name="a">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="b">A <see cref="Matrix3F"/> instance.</param>
		/// <returns>A new <see cref="Matrix3F"/> instance containing the result.</returns>
		public static Matrix3F operator*(Matrix3F a, Matrix3F b)
		{
			return Matrix3F.Multiply(a,b);
		}
		/// <summary>
		/// Transforms a given vector by a matrix.
		/// </summary>
		/// <param name="matrix">A <see cref="Matrix3F"/> instance.</param>
		/// <param name="vector">A <see cref="Vector3F"/> instance.</param>
		/// <returns>A new <see cref="Vector3F"/> instance containing the result.</returns>
		public static Vector3F operator*(Matrix3F matrix, Vector3F vector)
		{
			return Matrix3F.Transform(matrix, vector);
		}
		#endregion

		#region Indexing Operators
		/// <summary>
		/// Indexer allowing to access the matrix elements by an index
		/// where index = 2*row + column.
		/// </summary>
		public unsafe float this [int index] 
		{			
			get 
			{
				if (index < 0 || index >= 16)
					throw new IndexOutOfRangeException("Invalid matrix index!");

				fixed(float *f = &_m11) 
				{
					return *(f+index);
				}
			}
			set 
			{			
				if (index < 0 || index >= 16)
					throw new IndexOutOfRangeException("Invalid matrix index!");

				fixed(float *f = &_m11) 
				{
					*(f+index) = value;
				}
			}			
		}
		/// <summary>
		/// Indexer allowing to access the matrix elements by row and column.
		/// </summary>
		public float this[int row, int column]
		{
			get 
			{
				return this[ row*2 + column ];
			}
			set 
			{				
				this[ row*2 + column ] = value;
			}			
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions