コード例 #1
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Performs a Hermite spline interpolation.
        /// </summary>
        /// <param name="value1">First source position vector.</param>
        /// <param name="tangent1">First source tangent vector.</param>
        /// <param name="value2">Second source position vector.</param>
        /// <param name="tangent2">Second source tangent vector.</param>
        /// <param name="amount">Weighting factor.</param>
        /// <param name="result">When the method completes, contains the result of the Hermite spline interpolation.</param>
        public static void Hermite(ref Vector4D value1, ref Vector4D tangent1, ref Vector4D value2, ref Vector4D tangent2, double amount, out Vector4D result)
        {
            double squared = amount * amount;
            double cubed = amount * squared;
            double part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
            double part2 = (-2.0 * cubed) + (3.0 * squared);
            double part3 = (cubed - (2.0 * squared)) + amount;
            double part4 = cubed - squared;

            result = new Vector4D((((value1.X * part1) + (value2.X * part2)) + (tangent1.X * part3)) + (tangent2.X * part4),
                (((value1.Y * part1) + (value2.Y * part2)) + (tangent1.Y * part3)) + (tangent2.Y * part4),
                (((value1.Z * part1) + (value2.Z * part2)) + (tangent1.Z * part3)) + (tangent2.Z * part4),
                (((value1.W * part1) + (value2.W * part2)) + (tangent1.W * part3)) + (tangent2.W * part4));
        }
コード例 #2
0
ファイル: Vector3D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Performs a coordinate transformation using the given <see cref="SharpDX.Matrix"/>.
        /// </summary>
        /// <param name="coordinate">The coordinate vector to transform.</param>
        /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param>
        /// <param name="result">When the method completes, contains the transformed coordinates.</param>
        /// <remarks>
        /// A coordinate transform performs the transformation with the assumption that the w component
        /// is one. The four dimensional vector obtained from the transformation operation has each
        /// component in the vector divided by the w component. This forces the w component to be one and
        /// therefore makes the vector homogeneous. The homogeneous vector is often preferred when working
        /// with coordinates as the w component can safely be ignored.
        /// </remarks>
        public static void TransformCoordinate(ref Vector3D coordinate, ref MatrixD transform, out Vector3D result)
        {
            Vector4D vector = new Vector4D();
            vector.X = (coordinate.X * transform.M11) + (coordinate.Y * transform.M21) + (coordinate.Z * transform.M31) + transform.M41;
            vector.Y = (coordinate.X * transform.M12) + (coordinate.Y * transform.M22) + (coordinate.Z * transform.M32) + transform.M42;
            vector.Z = (coordinate.X * transform.M13) + (coordinate.Y * transform.M23) + (coordinate.Z * transform.M33) + transform.M43;
            vector.W = 1f / ((coordinate.X * transform.M14) + (coordinate.Y * transform.M24) + (coordinate.Z * transform.M34) + transform.M44);

            result = new Vector3D(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W);
        }
コード例 #3
0
ファイル: MatrixD.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Creates a MatrixD that flattens geometry into a shadow.
        /// </summary>
        /// <param name="light">The light direction. If the W component is 0, the light is directional light; if the
        /// W component is 1, the light is a point light.</param>
        /// <param name="plane">The plane onto which to project the geometry as a shadow. This parameter is assumed to be normalized.</param>
        /// <param name="result">When the method completes, contains the shadow MatrixD.</param>
        public static void Shadow(ref Vector4D light, ref Plane plane, out MatrixD result)
        {
            double dot = (plane.Normal.X * light.X) + (plane.Normal.Y * light.Y) + (plane.Normal.Z * light.Z) + (plane.D * light.W);
            double x = -plane.Normal.X;
            double y = -plane.Normal.Y;
            double z = -plane.Normal.Z;
            double d = -plane.D;

            result.M11 = (x * light.X) + dot;
            result.M21 = y * light.X;
            result.M31 = z * light.X;
            result.M41 = d * light.X;
            result.M12 = x * light.Y;
            result.M22 = (y * light.Y) + dot;
            result.M32 = z * light.Y;
            result.M42 = d * light.Y;
            result.M13 = x * light.Z;
            result.M23 = y * light.Z;
            result.M33 = (z * light.Z) + dot;
            result.M43 = d * light.Z;
            result.M14 = x * light.W;
            result.M24 = y * light.W;
            result.M34 = z * light.W;
            result.M44 = (d * light.W) + dot;
        }
コード例 #4
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Transforms a 4D vector by the given <see cref="SharpDX.Quaternion"/> rotation.
 /// </summary>
 /// <param name="vector">The vector to rotate.</param>
 /// <param name="rotation">The <see cref="SharpDX.Quaternion"/> rotation to apply.</param>
 /// <returns>The transformed <see cref="SharpDX.Vector4D"/>.</returns>
 public static Vector4D Transform(Vector4D vector, Quaternion rotation)
 {
     Vector4D result;
     Transform(ref vector, ref rotation, out result);
     return result;
 }
コード例 #5
0
ファイル: Vector3D.cs プロジェクト: ukitake/Stratum
 public static void Transform(ref Vector3D vector, ref MatrixD transform, out Vector4D result)
 {
     result = new Vector4D(
         (vector.X * transform.M11) + (vector.Y * transform.M21) + (vector.Z * transform.M31) + transform.M41,
         (vector.X * transform.M12) + (vector.Y * transform.M22) + (vector.Z * transform.M32) + transform.M42,
         (vector.X * transform.M13) + (vector.Y * transform.M23) + (vector.Z * transform.M33) + transform.M43,
         (vector.X * transform.M14) + (vector.Y * transform.M24) + (vector.Z * transform.M34) + transform.M44);
 }
コード例 #6
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Performs a cubic interpolation between two vectors.
 /// </summary>
 /// <param name="start">Start vector.</param>
 /// <param name="end">End vector.</param>
 /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
 /// <returns>The cubic interpolation of the two vectors.</returns>
 public static Vector4D SmoothStep(Vector4D start, Vector4D end, double amount)
 {
     Vector4D result;
     SmoothStep(ref start, ref end, amount, out result);
     return result;
 }
コード例 #7
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Subtracts two vectors.
 /// </summary>
 /// <param name="left">The first vector to subtract.</param>
 /// <param name="right">The second vector to subtract.</param>
 /// <returns>The difference of the two vectors.</returns>
 public static Vector4D Subtract(Vector4D left, Vector4D right)
 {
     return new Vector4D(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
 }
コード例 #8
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Modulates a vector with another by performing component-wise multiplication.
 /// </summary>
 /// <param name="left">The first vector to modulate.</param>
 /// <param name="right">The second vector to modulate.</param>
 /// <param name="result">When the method completes, contains the modulated vector.</param>
 public static void Modulate(ref Vector4D left, ref Vector4D right, out Vector4D result)
 {
     result = new Vector4D(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
 }
コード例 #9
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Modulates a vector with another by performing component-wise multiplication.
 /// </summary>
 /// <param name="left">The first vector to modulate.</param>
 /// <param name="right">The second vector to modulate.</param>
 /// <returns>The modulated vector.</returns>
 public static Vector4D Modulate(Vector4D left, Vector4D right)
 {
     return new Vector4D(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
 }
コード例 #10
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Returns a vector containing the smallest components of the specified vectors.
 /// </summary>
 /// <param name="left">The first source vector.</param>
 /// <param name="right">The second source vector.</param>
 /// <param name="result">When the method completes, contains an new vector composed of the smallest components of the source vectors.</param>
 public static void Min(ref Vector4D left, ref Vector4D right, out Vector4D result)
 {
     result.X = (left.X < right.X) ? left.X : right.X;
     result.Y = (left.Y < right.Y) ? left.Y : right.Y;
     result.Z = (left.Z < right.Z) ? left.Z : right.Z;
     result.W = (left.W < right.W) ? left.W : right.W;
 }
コード例 #11
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Returns a vector containing the smallest components of the specified vectors.
 /// </summary>
 /// <param name="left">The first source vector.</param>
 /// <param name="right">The second source vector.</param>
 /// <returns>A vector containing the smallest components of the source vectors.</returns>
 public static Vector4D Min(Vector4D left, Vector4D right)
 {
     Vector4D result;
     Min(ref left, ref right, out result);
     return result;
 }
コード例 #12
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Returns a vector containing the largest components of the specified vectors.
 /// </summary>
 /// <param name="left">The first source vector.</param>
 /// <param name="right">The second source vector.</param>
 /// <param name="result">When the method completes, contains an new vector composed of the largest components of the source vectors.</param>
 public static void Max(ref Vector4D left, ref Vector4D right, out Vector4D result)
 {
     result.X = (left.X > right.X) ? left.X : right.X;
     result.Y = (left.Y > right.Y) ? left.Y : right.Y;
     result.Z = (left.Z > right.Z) ? left.Z : right.Z;
     result.W = (left.W > right.W) ? left.W : right.W;
 }
コード例 #13
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Performs a linear interpolation between two vectors.
 /// </summary>
 /// <param name="start">Start vector.</param>
 /// <param name="end">End vector.</param>
 /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
 /// <param name="result">When the method completes, contains the linear interpolation of the two vectors.</param>
 /// <remarks>
 /// This method performs the linear interpolation based on the following formula.
 /// <code>start + (end - start) * amount</code>
 /// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned. 
 /// </remarks>
 public static void Lerp(ref Vector4D start, ref Vector4D end, double amount, out Vector4D result)
 {
     result.X = start.X + ((end.X - start.X) * amount);
     result.Y = start.Y + ((end.Y - start.Y) * amount);
     result.Z = start.Z + ((end.Z - start.Z) * amount);
     result.W = start.W + ((end.W - start.W) * amount);
 }
コード例 #14
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Performs a Hermite spline interpolation.
 /// </summary>
 /// <param name="value1">First source position vector.</param>
 /// <param name="tangent1">First source tangent vector.</param>
 /// <param name="value2">Second source position vector.</param>
 /// <param name="tangent2">Second source tangent vector.</param>
 /// <param name="amount">Weighting factor.</param>
 /// <returns>The result of the Hermite spline interpolation.</returns>
 public static Vector4D Hermite(Vector4D value1, Vector4D tangent1, Vector4D value2, Vector4D tangent2, double amount)
 {
     Vector4D result;
     Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
     return result;
 }
コード例 #15
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Orthonormalizes a list of vectors.
        /// </summary>
        /// <param name="destination">The list of orthonormalized vectors.</param>
        /// <param name="source">The list of vectors to orthonormalize.</param>
        /// <remarks>
        /// <para>Orthonormalization is the process of making all vectors orthogonal to each
        /// other and making all vectors of unit length. This means that any given vector will
        /// be orthogonal to any other given vector in the list.</para>
        /// <para>Because this method uses the modified Gram-Schmidt process, the resulting vectors
        /// tend to be numerically unstable. The numeric stability decreases according to the vectors
        /// position in the list so that the first vector is the most stable and the last vector is the
        /// least stable.</para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="source"/> or <paramref name="destination"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="destination"/> is shorter in length than <paramref name="source"/>.</exception>
        public static void Orthonormalize(Vector4D[] destination, params Vector4D[] source)
        {
            //Uses the modified Gram-Schmidt process.
            //Because we are making unit vectors, we can optimize the math for orthogonalization
            //and simplify the projection operation to remove the division.
            //q1 = m1 / |m1|
            //q2 = (m2 - (q1 ⋅ m2) * q1) / |m2 - (q1 ⋅ m2) * q1|
            //q3 = (m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2) / |m3 - (q1 ⋅ m3) * q1 - (q2 ⋅ m3) * q2|
            //q4 = (m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3) / |m4 - (q1 ⋅ m4) * q1 - (q2 ⋅ m4) * q2 - (q3 ⋅ m4) * q3|
            //q5 = ...

            if (source == null)
                throw new ArgumentNullException("source");
            if (destination == null)
                throw new ArgumentNullException("destination");
            if (destination.Length < source.Length)
                throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array.");

            for (int i = 0; i < source.Length; ++i)
            {
                Vector4D newvector = source[i];

                for (int r = 0; r < i; ++r)
                {
                    newvector -= Vector4D.Dot(destination[r], newvector) * destination[r];
                }

                newvector.Normalize();
                destination[i] = newvector;
            }
        }
コード例 #16
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Scales a vector by the given value.
 /// </summary>
 /// <param name="value">The vector to scale.</param>
 /// <param name="scale">The amount by which to scale the vector.</param>
 /// <param name="result">When the method completes, contains the scaled vector.</param>
 public static void Multiply(ref Vector4D value, double scale, out Vector4D result)
 {
     result = new Vector4D(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
 }
コード例 #17
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Performs a cubic interpolation between two vectors.
        /// </summary>
        /// <param name="start">Start vector.</param>
        /// <param name="end">End vector.</param>
        /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
        /// <param name="result">When the method completes, contains the cubic interpolation of the two vectors.</param>
        public static void SmoothStep(ref Vector4D start, ref Vector4D end, double amount, out Vector4D result)
        {
            amount = (amount > 1.0) ? 1.0 : ((amount < 0.0) ? 0.0 : amount);
            amount = (amount * amount) * (3.0 - (2.0 * amount));

            result.X = start.X + ((end.X - start.X) * amount);
            result.Y = start.Y + ((end.Y - start.Y) * amount);
            result.Z = start.Z + ((end.Z - start.Z) * amount);
            result.W = start.W + ((end.W - start.W) * amount);
        }
コード例 #18
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Scales a vector by the given value.
 /// </summary>
 /// <param name="value">The vector to scale.</param>
 /// <param name="scale">The amount by which to scale the vector.</param>
 /// <returns>The scaled vector.</returns>
 public static Vector4D Multiply(Vector4D value, double scale)
 {
     return new Vector4D(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
 }
コード例 #19
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Subtracts two vectors.
 /// </summary>
 /// <param name="left">The first vector to subtract.</param>
 /// <param name="right">The second vector to subtract.</param>
 /// <param name="result">When the method completes, contains the difference of the two vectors.</param>
 public static void Subtract(ref Vector4D left, ref Vector4D right, out Vector4D result)
 {
     result = new Vector4D(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
 }
コード例 #20
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Reverses the direction of a given vector.
 /// </summary>
 /// <param name="value">The vector to negate.</param>
 /// <param name="result">When the method completes, contains a vector facing in the opposite direction.</param>
 public static void Negate(ref Vector4D value, out Vector4D result)
 {
     result = new Vector4D(-value.X, -value.Y, -value.Z, -value.W);
 }
コード例 #21
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Transforms a 4D vector by the given <see cref="SharpDX.Quaternion"/> rotation.
        /// </summary>
        /// <param name="vector">The vector to rotate.</param>
        /// <param name="rotation">The <see cref="SharpDX.Quaternion"/> rotation to apply.</param>
        /// <param name="result">When the method completes, contains the transformed <see cref="SharpDX.Vector4D"/>.</param>
        public static void Transform(ref Vector4D vector, ref Quaternion rotation, out Vector4D result)
        {
            double x = rotation.X + rotation.X;
            double y = rotation.Y + rotation.Y;
            double z = rotation.Z + rotation.Z;
            double wx = rotation.W * x;
            double wy = rotation.W * y;
            double wz = rotation.W * z;
            double xx = rotation.X * x;
            double xy = rotation.X * y;
            double xz = rotation.X * z;
            double yy = rotation.Y * y;
            double yz = rotation.Y * z;
            double zz = rotation.Z * z;

            result = new Vector4D(
                ((vector.X * ((1.0 - yy) - zz)) + (vector.Y * (xy - wz))) + (vector.Z * (xz + wy)),
                ((vector.X * (xy + wz)) + (vector.Y * ((1.0 - xx) - zz))) + (vector.Z * (yz - wx)),
                ((vector.X * (xz - wy)) + (vector.Y * (yz + wx))) + (vector.Z * ((1.0 - xx) - yy)),
                vector.W);
        }
コード例 #22
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Reverses the direction of a given vector.
 /// </summary>
 /// <param name="value">The vector to negate.</param>
 /// <returns>A vector facing in the opposite direction.</returns>
 public static Vector4D Negate(Vector4D value)
 {
     return new Vector4D(-value.X, -value.Y, -value.Z, -value.W);
 }
コード例 #23
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Transforms an array of vectors by the given <see cref="SharpDX.Quaternion"/> rotation.
        /// </summary>
        /// <param name="source">The array of vectors to transform.</param>
        /// <param name="rotation">The <see cref="SharpDX.Quaternion"/> rotation to apply.</param>
        /// <param name="destination">The array for which the transformed vectors are stored.
        /// This array may be the same array as <paramref name="source"/>.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="source"/> or <paramref name="destination"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="destination"/> is shorter in length than <paramref name="source"/>.</exception>
        public static void Transform(Vector4D[] source, ref Quaternion rotation, Vector4D[] destination)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (destination == null)
                throw new ArgumentNullException("destination");
            if (destination.Length < source.Length)
                throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array.");

            double x = rotation.X + rotation.X;
            double y = rotation.Y + rotation.Y;
            double z = rotation.Z + rotation.Z;
            double wx = rotation.W * x;
            double wy = rotation.W * y;
            double wz = rotation.W * z;
            double xx = rotation.X * x;
            double xy = rotation.X * y;
            double xz = rotation.X * z;
            double yy = rotation.Y * y;
            double yz = rotation.Y * z;
            double zz = rotation.Z * z;

            double num1 = ((1.0 - yy) - zz);
            double num2 = (xy - wz);
            double num3 = (xz + wy);
            double num4 = (xy + wz);
            double num5 = ((1.0 - xx) - zz);
            double num6 = (yz - wx);
            double num7 = (xz - wy);
            double num8 = (yz + wx);
            double num9 = ((1.0 - xx) - yy);

            for (int i = 0; i < source.Length; ++i)
            {
                destination[i] = new Vector4D(
                    ((source[i].X * num1) + (source[i].Y * num2)) + (source[i].Z * num3),
                    ((source[i].X * num4) + (source[i].Y * num5)) + (source[i].Z * num6),
                    ((source[i].X * num7) + (source[i].Y * num8)) + (source[i].Z * num9),
                    source[i].W);
            }
        }
コード例 #24
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Converts the vector into a unit vector.
 /// </summary>
 /// <param name="value">The vector to normalize.</param>
 /// <param name="result">When the method completes, contains the normalized vector.</param>
 public static void Normalize(ref Vector4D value, out Vector4D result)
 {
     Vector4D temp = value;
     result = temp;
     result.Normalize();
 }
コード例 #25
0
ファイル: Vector3D.cs プロジェクト: ukitake/Stratum
        public static void Transform(Vector3D[] source, ref MatrixD transform, Vector4D[] destination)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (destination == null)
                throw new ArgumentNullException("destination");
            if (destination.Length < source.Length)
                throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array.");

            for (int i = 0; i < source.Length; ++i)
            {
                Transform(ref source[i], ref transform, out destination[i]);
            }
        }
コード例 #26
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Converts the vector into a unit vector.
 /// </summary>
 /// <param name="value">The vector to normalize.</param>
 /// <returns>The normalized vector.</returns>
 public static Vector4D Normalize(Vector4D value)
 {
     value.Normalize();
     return value;
 }
コード例 #27
0
ファイル: MatrixD.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Brings the MatrixD into reduced row echelon form using elementary row operations.
        /// </summary>
        /// <param name="value">The MatrixD to put into reduced row echelon form.</param>
        /// <param name="augment">The fifth column of the MatrixD.</param>
        /// <param name="result">When the method completes, contains the resultant MatrixD after the operation.</param>
        /// <param name="augmentResult">When the method completes, contains the resultant fifth column of the MatrixD.</param>
        /// <remarks>
        /// <para>The fifth column is often called the augmented part of the MatrixD. This is because the fifth
        /// column is really just an extension of the MatrixD so that there is a place to put all of the
        /// non-zero components after the operation is complete.</para>
        /// <para>Often times the resultant MatrixD will the identity MatrixD or a MatrixD similar to the identity
        /// MatrixD. Sometimes, however, that is not possible and numbers other than zero and one may appear.</para>
        /// <para>This method can be used to solve systems of linear equations. Upon completion of this method,
        /// the <paramref name="augmentResult"/> will contain the solution for the system. It is up to the user
        /// to analyze both the input and the result to determine if a solution really exists.</para>
        /// </remarks>
        public static void ReducedRowEchelonForm(ref MatrixD value, ref Vector4D augment, out MatrixD result, out Vector4D augmentResult)
        {
            //Source: http://rosettacode.org
            //Reference: http://rosettacode.org/wiki/Reduced_row_echelon_form

            double[,] MatrixD = new double[4, 5];

            MatrixD[0, 0] = value[0, 0];
            MatrixD[0, 1] = value[0, 1];
            MatrixD[0, 2] = value[0, 2];
            MatrixD[0, 3] = value[0, 3];
            MatrixD[0, 4] = augment[0];

            MatrixD[1, 0] = value[1, 0];
            MatrixD[1, 1] = value[1, 1];
            MatrixD[1, 2] = value[1, 2];
            MatrixD[1, 3] = value[1, 3];
            MatrixD[1, 4] = augment[1];

            MatrixD[2, 0] = value[2, 0];
            MatrixD[2, 1] = value[2, 1];
            MatrixD[2, 2] = value[2, 2];
            MatrixD[2, 3] = value[2, 3];
            MatrixD[2, 4] = augment[2];

            MatrixD[3, 0] = value[3, 0];
            MatrixD[3, 1] = value[3, 1];
            MatrixD[3, 2] = value[3, 2];
            MatrixD[3, 3] = value[3, 3];
            MatrixD[3, 4] = augment[3];

            int lead = 0;
            int rowcount = 4;
            int columncount = 5;

            for (int r = 0; r < rowcount; r++)
            {
                if (columncount <= lead)
                    break;

                int i = r;

                while (MatrixD[i, lead] == 0)
                {
                    i++;

                    if (i == rowcount)
                    {
                        i = r;
                        lead++;

                        if (columncount == lead)
                            break;
                    }
                }

                for (int j = 0; j < columncount; j++)
                {
                    double temp = MatrixD[r, j];
                    MatrixD[r, j] = MatrixD[i, j];
                    MatrixD[i, j] = temp;
                }

                double div = MatrixD[r, lead];

                for (int j = 0; j < columncount; j++)
                {
                    MatrixD[r, j] /= div;
                }

                for (int j = 0; j < rowcount; j++)
                {
                    if (j != r)
                    {
                        double sub = MatrixD[j, lead];
                        for (int k = 0; k < columncount; k++) MatrixD[j, k] -= (sub * MatrixD[r, k]);
                    }
                }

                lead++;
            }

            result.M11 = MatrixD[0, 0];
            result.M12 = MatrixD[0, 1];
            result.M13 = MatrixD[0, 2];
            result.M14 = MatrixD[0, 3];

            result.M21 = MatrixD[1, 0];
            result.M22 = MatrixD[1, 1];
            result.M23 = MatrixD[1, 2];
            result.M24 = MatrixD[1, 3];

            result.M31 = MatrixD[2, 0];
            result.M32 = MatrixD[2, 1];
            result.M33 = MatrixD[2, 2];
            result.M34 = MatrixD[2, 3];

            result.M41 = MatrixD[3, 0];
            result.M42 = MatrixD[3, 1];
            result.M43 = MatrixD[3, 2];
            result.M44 = MatrixD[3, 3];

            augmentResult.X = MatrixD[0, 4];
            augmentResult.Y = MatrixD[1, 4];
            augmentResult.Z = MatrixD[2, 4];
            augmentResult.W = MatrixD[3, 4];
        }
コード例 #28
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
        /// <summary>
        /// Orthogonalizes a list of vectors.
        /// </summary>
        /// <param name="destination">The list of orthogonalized vectors.</param>
        /// <param name="source">The list of vectors to orthogonalize.</param>
        /// <remarks>
        /// <para>Orthogonalization is the process of making all vectors orthogonal to each other. This
        /// means that any given vector in the list will be orthogonal to any other given vector in the
        /// list.</para>
        /// <para>Because this method uses the modified Gram-Schmidt process, the resulting vectors
        /// tend to be numerically unstable. The numeric stability decreases according to the vectors
        /// position in the list so that the first vector is the most stable and the last vector is the
        /// least stable.</para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="source"/> or <paramref name="destination"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="destination"/> is shorter in length than <paramref name="source"/>.</exception>
        public static void Orthogonalize(Vector4D[] destination, params Vector4D[] source)
        {
            //Uses the modified Gram-Schmidt process.
            //q1 = m1
            //q2 = m2 - ((q1 ⋅ m2) / (q1 ⋅ q1)) * q1
            //q3 = m3 - ((q1 ⋅ m3) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m3) / (q2 ⋅ q2)) * q2
            //q4 = m4 - ((q1 ⋅ m4) / (q1 ⋅ q1)) * q1 - ((q2 ⋅ m4) / (q2 ⋅ q2)) * q2 - ((q3 ⋅ m4) / (q3 ⋅ q3)) * q3
            //q5 = ...

            if (source == null)
                throw new ArgumentNullException("source");
            if (destination == null)
                throw new ArgumentNullException("destination");
            if (destination.Length < source.Length)
                throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array.");

            for (int i = 0; i < source.Length; ++i)
            {
                Vector4D newvector = source[i];

                for (int r = 0; r < i; ++r)
                {
                    newvector -= (Vector4D.Dot(destination[r], newvector) / Vector4D.Dot(destination[r], destination[r])) * destination[r];
                }

                destination[i] = newvector;
            }
        }
コード例 #29
0
ファイル: MatrixD.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Creates a MatrixD that flattens geometry into a shadow.
 /// </summary>
 /// <param name="light">The light direction. If the W component is 0, the light is directional light; if the
 /// W component is 1, the light is a point light.</param>
 /// <param name="plane">The plane onto which to project the geometry as a shadow. This parameter is assumed to be normalized.</param>
 /// <returns>The shadow MatrixD.</returns>
 public static MatrixD Shadow(Vector4D light, Plane plane)
 {
     MatrixD result;
     Shadow(ref light, ref plane, out result);
     return result;
 }
コード例 #30
0
ファイル: Vector4D.cs プロジェクト: ukitake/Stratum
 /// <summary>
 /// Calculates the dot product of two vectors.
 /// </summary>
 /// <param name="left">First source vector.</param>
 /// <param name="right">Second source vector.</param>
 /// <returns>The dot product of the two vectors.</returns>
 public static double Dot(Vector4D left, Vector4D right)
 {
     return (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W);
 }