/// <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)); }
/// <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); }
/// <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; }
/// <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; }
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); }
/// <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; }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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; }
/// <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; } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); } }
/// <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(); }
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]); } }
/// <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; }
/// <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]; }
/// <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; } }
/// <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; }
/// <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); }