Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / C#

Space and Matrix Transformations - Building a 3D Engine

Rate me:
Please Sign up or sign in to vote.
4.84/5 (13 votes)
4 Sep 2009CPOL8 min read 94.8K   6.1K   101  
This Article Describes How to Navigate 3D Space
using System;
using System.Collections.Generic;
using System.Text;

namespace AGE_Engine3D.Math
{
    /// <summary>
    /// Represents a location in 3D space, contains all the standard 
    /// vector operations for a 3-dimensional vector.
    /// </summary>
    public struct AGE_Vector3Df
    {
        #region ---Public Fields---
        /// <summary>
        /// The X component of the vector.
        /// </summary>
        public float X;

        /// <summary>
        /// The Y component of the vector.
        /// </summary>
        public float Y;

        /// <summary>
        /// The Z component of the vector.
        /// </summary>
        public float Z;
        #endregion 

        #region ---Interfaces---
        public float _X
        {
            get { return this.X; }
            set { this.X = value; }
        }
        public float _Y
        {
            get { return this.Y; }
            set { this.Y = value; }
        }
        public float _Z
        {
            get { return this.Z; }
            set { this.Z = value; }
        }
        #endregion

        #region --- Methods ---
        #region Constructors
        /// <summary>
        /// Creates a new vector set to (x, y, z).
        /// </summary>
        /// <param name="x">The X coordinate.</param>
        /// <param name="y">The Y coordinate.</param>
        /// <param name="z">The Z coordinate.</param>
        public AGE_Vector3Df(float x, float y, float z)
        {
            this.X = x;
            this.Y = y;
            this.Z = z;
        }

        /// <summary>
        /// Creates a new vector set to the values of the given vector.
        /// </summary>
        /// <param name="vector">The vector whose values we'll use.</param>
        public AGE_Vector3Df(ref AGE_Vector3Df vector)
        {
            this.X = vector.X;
            this.Y = vector.Y;
            this.Z = vector.Z;
        }

        public AGE_Vector3Df(ref float[] Data)
        {
            this.X = Data[0];
            this.Y = Data[1];
            this.Z = Data[2];
        }
        #endregion Constructors

        #region Magnitude
        public float MagSq()
        {
            return (this.X * this.X + this.Y * this.Y + this.Z * this.Z);
        }
        public float Mag()
        {
            return (float)System.Math.Sqrt((double)this.MagSq());
        }
        #endregion

        #region Vector Operations
        public AGE_Vector3Df UnitVector()
        {
            float tmp = 1 / this.Mag();
            AGE_Vector3Df result = this * tmp;
            return result;
        }
        public static float DotProduct(ref AGE_Vector3Df Vector1, ref AGE_Vector3Df Vector2)
        {
            float result = Vector1.X * Vector2.X +
                           Vector1.Y * Vector2.Y +
                           Vector1.Z * Vector2.Z;
            return result;
        }
        public static void CrossProduct(ref AGE_Vector3Df VectorLeft, ref AGE_Vector3Df VectorRight, out AGE_Vector3Df Result)
        {
            Result = new AGE_Vector3Df((VectorLeft.Y * VectorRight.Z - VectorLeft.Z * VectorRight.Y),
                                (VectorLeft.Z * VectorRight.X - VectorLeft.X * VectorRight.Z),
                                VectorLeft.X * VectorRight.Y - VectorLeft.Y * VectorRight.X);
        }
        public static AGE_Vector3Df CrossProduct(ref AGE_Vector3Df VectorLeft, ref AGE_Vector3Df VectorRight)
        {
            return new AGE_Vector3Df((VectorLeft.Y * VectorRight.Z - VectorLeft.Z * VectorRight.Y),
                                (VectorLeft.Z * VectorRight.X - VectorLeft.X * VectorRight.Z),
                                VectorLeft.X * VectorRight.Y - VectorLeft.Y * VectorRight.X);
        }
        #endregion

        #region Misc.
        public override string ToString()
        {
            string result = "X = " + this.X + "     Y = " + this.Y + "     Z = " + this.Z;
            return result;
        }
        public float[] ToArray3f()
        {
            float[] result = new float[] { this.X, this.Y, this.Z };
            return result;
        }
        #endregion
        #endregion

        #region --- Operator Overloads ---
        #region AGE_Vector3Df operator +(AGE_Vector3Df a, AGE_Vector3Df b)
        /// <summary>
        /// Adds two vectors.  Result is (a.X + b.X, a.Y + b.Y, a.Z + b.Z).
        /// </summary>
        /// <param name="a">First vector.</param>
        /// <param name="b">Second vector.</param>
        /// <returns></returns>
        public static AGE_Vector3Df operator +(AGE_Vector3Df a, AGE_Vector3Df b)
        {
            return new AGE_Vector3Df(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
        }
        #endregion AGE_Vector3Df operator +(AGE_Vector3Df a, AGE_Vector3Df b)

        #region AGE_Vector3Df operator *(AGE_Vector3Df vector, float scalar)
        /// <summary>
        /// Multiply vector by a scalar.  Result is (vector.X * scalar, vector.Y * scalar, vector.Z * scalar).
        /// </summary>
        /// <param name="vector">The vector.</param>
        /// <param name="scalar">The scalar</param>
        /// <returns></returns>
        public static AGE_Vector3Df operator *(AGE_Vector3Df vector, float scalar)
        {
            return new AGE_Vector3Df(vector.X * scalar, vector.Y * scalar, vector.Z * scalar);
        }
        #endregion AGE_Vector3Df operator *(AGE_Vector3Df vector, float scalar)

        #region AGE_Vector3Df operator -(AGE_Vector3Df a, AGE_Vector3Df b)
        /// <summary>
        /// Subtract two vectors.  Result is (a.X - b.X, a.Y - b.Y, a.Z - b.Z).
        /// </summary>
        /// <param name="a">The first vector.</param>
        /// <param name="b">The second vector.</param>
        /// <returns></returns>
        public static AGE_Vector3Df operator -(AGE_Vector3Df a, AGE_Vector3Df b)
        {
            return new AGE_Vector3Df(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
        }
        #endregion AGE_Vector3Df operator -(AGE_Vector3Df a, AGE_Vector3Df b)
        #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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Lea+Elliott, Inc.
United States United States
I am a licensed Electrical Engineer at Lea+Elliott, Inc. We specialize in the planning, procurement and implementation of transportation systems, with special emphasis on automated and emerging technologies.

Comments and Discussions