2 Copyright (c) 2006 - 2008 The Open Toolkit library.
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 using System.Runtime.InteropServices;
25 using System.Xml.Serialization;
29 /// <summary>Represents a 4D vector using four single-precision floating-point numbers.</summary>
31 /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats.
34 [StructLayout(LayoutKind.Sequential)]
35 public struct Vector4 : IEquatable<Vector4>
38 /// The X component of the Vector4.
43 /// The Y component of the Vector4.
48 /// The Z component of the Vector4.
53 /// The W component of the Vector4.
58 /// Defines a unit-length Vector4 that points towards the X-axis.
60 public static readonly Vector4 UnitX = new Vector4(1, 0, 0, 0);
63 /// Defines a unit-length Vector4 that points towards the Y-axis.
65 public static readonly Vector4 UnitY = new Vector4(0, 1, 0, 0);
68 /// Defines a unit-length Vector4 that points towards the Z-axis.
70 public static readonly Vector4 UnitZ = new Vector4(0, 0, 1, 0);
73 /// Defines a unit-length Vector4 that points towards the W-axis.
75 public static readonly Vector4 UnitW = new Vector4(0, 0, 0, 1);
78 /// Defines a zero-length Vector4.
80 public static readonly Vector4 Zero = new Vector4(0, 0, 0, 0);
83 /// Defines an instance with all components set to 1.
85 public static readonly Vector4 One = new Vector4(1, 1, 1, 1);
88 /// Defines the size of the Vector4 struct in bytes.
90 public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4());
93 /// Constructs a new instance.
95 /// <param name="value">The value that will initialize this instance.</param>
96 public Vector4(float value)
105 /// Constructs a new Vector4.
107 /// <param name="x">The x component of the Vector4.</param>
108 /// <param name="y">The y component of the Vector4.</param>
109 /// <param name="z">The z component of the Vector4.</param>
110 /// <param name="w">The w component of the Vector4.</param>
111 public Vector4(float x, float y, float z, float w)
120 /// Constructs a new Vector4 from the given Vector2.
122 /// <param name="v">The Vector2 to copy components from.</param>
123 public Vector4(Vector2 v)
132 /// Constructs a new Vector4 from the given Vector3.
133 /// The w component is initialized to 0.
135 /// <param name="v">The Vector3 to copy components from.</param>
136 /// <remarks><seealso cref="Vector4(Vector3, float)"/></remarks>
137 public Vector4(Vector3 v)
146 /// Constructs a new Vector4 from the specified Vector3 and w component.
148 /// <param name="v">The Vector3 to copy components from.</param>
149 /// <param name="w">The w component of the new Vector4.</param>
150 public Vector4(Vector3 v, float w)
159 /// Constructs a new Vector4 from the given Vector4.
161 /// <param name="v">The Vector4 to copy components from.</param>
162 public Vector4(Vector4 v)
171 /// Gets or sets the value at the index of the Vector.
173 public float this[int index] {
191 throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
211 throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
217 /// Gets the length (magnitude) of the vector.
219 /// <see cref="LengthFast"/>
220 /// <seealso cref="LengthSquared"/>
225 return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
230 /// Gets an approximation of the vector length (magnitude).
233 /// This property uses an approximation of the square root function to calculate vector magnitude, with
234 /// an upper error bound of 0.001.
236 /// <see cref="Length"/>
237 /// <seealso cref="LengthSquared"/>
238 public float LengthFast
242 return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
247 /// Gets the square of the vector length (magnitude).
250 /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
253 /// <see cref="Length"/>
254 /// <seealso cref="LengthFast"/>
255 public float LengthSquared
259 return X * X + Y * Y + Z * Z + W * W;
264 /// Returns a copy of the Vector4 scaled to unit length.
266 public Vector4 Normalized()
274 /// Scales the Vector4 to unit length.
276 public void Normalize()
278 float scale = 1.0f / this.Length;
286 /// Scales the Vector4 to approximately unit length.
288 public void NormalizeFast()
290 float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
298 /// Adds two vectors.
300 /// <param name="a">Left operand.</param>
301 /// <param name="b">Right operand.</param>
302 /// <returns>Result of operation.</returns>
303 public static Vector4 Add(Vector4 a, Vector4 b)
305 Add(ref a, ref b, out a);
310 /// Adds two vectors.
312 /// <param name="a">Left operand.</param>
313 /// <param name="b">Right operand.</param>
314 /// <param name="result">Result of operation.</param>
315 public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result)
317 result.X = a.X + b.X;
318 result.Y = a.Y + b.Y;
319 result.Z = a.Z + b.Z;
320 result.W = a.W + b.W;
324 /// Subtract one Vector from another
326 /// <param name="a">First operand</param>
327 /// <param name="b">Second operand</param>
328 /// <returns>Result of subtraction</returns>
329 public static Vector4 Subtract(Vector4 a, Vector4 b)
331 Subtract(ref a, ref b, out a);
336 /// Subtract one Vector from another
338 /// <param name="a">First operand</param>
339 /// <param name="b">Second operand</param>
340 /// <param name="result">Result of subtraction</param>
341 public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result)
343 result.X = a.X - b.X;
344 result.Y = a.Y - b.Y;
345 result.Z = a.Z - b.Z;
346 result.W = a.W - b.W;
350 /// Multiplies a vector by a scalar.
352 /// <param name="vector">Left operand.</param>
353 /// <param name="scale">Right operand.</param>
354 /// <returns>Result of the operation.</returns>
355 public static Vector4 Multiply(Vector4 vector, float scale)
357 Multiply(ref vector, scale, out vector);
362 /// Multiplies a vector by a scalar.
364 /// <param name="vector">Left operand.</param>
365 /// <param name="scale">Right operand.</param>
366 /// <param name="result">Result of the operation.</param>
367 public static void Multiply(ref Vector4 vector, float scale, out Vector4 result)
369 result.X = vector.X * scale;
370 result.Y = vector.Y * scale;
371 result.Z = vector.Z * scale;
372 result.W = vector.W * scale;
376 /// Multiplies a vector by the components a vector (scale).
378 /// <param name="vector">Left operand.</param>
379 /// <param name="scale">Right operand.</param>
380 /// <returns>Result of the operation.</returns>
381 public static Vector4 Multiply(Vector4 vector, Vector4 scale)
383 Multiply(ref vector, ref scale, out vector);
388 /// Multiplies a vector by the components of a vector (scale).
390 /// <param name="vector">Left operand.</param>
391 /// <param name="scale">Right operand.</param>
392 /// <param name="result">Result of the operation.</param>
393 public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
395 result.X = vector.X * scale.X;
396 result.Y = vector.Y * scale.Y;
397 result.Z = vector.Z * scale.Z;
398 result.W = vector.W * scale.W;
402 /// Divides a vector by a scalar.
404 /// <param name="vector">Left operand.</param>
405 /// <param name="scale">Right operand.</param>
406 /// <returns>Result of the operation.</returns>
407 public static Vector4 Divide(Vector4 vector, float scale)
409 Divide(ref vector, scale, out vector);
414 /// Divides a vector by a scalar.
416 /// <param name="vector">Left operand.</param>
417 /// <param name="scale">Right operand.</param>
418 /// <param name="result">Result of the operation.</param>
419 public static void Divide(ref Vector4 vector, float scale, out Vector4 result)
421 result.X = vector.X / scale;
422 result.Y = vector.Y / scale;
423 result.Z = vector.Z / scale;
424 result.W = vector.W / scale;
428 /// Divides a vector by the components of a vector (scale).
430 /// <param name="vector">Left operand.</param>
431 /// <param name="scale">Right operand.</param>
432 /// <returns>Result of the operation.</returns>
433 public static Vector4 Divide(Vector4 vector, Vector4 scale)
435 Divide(ref vector, ref scale, out vector);
440 /// Divide a vector by the components of a vector (scale).
442 /// <param name="vector">Left operand.</param>
443 /// <param name="scale">Right operand.</param>
444 /// <param name="result">Result of the operation.</param>
445 public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result)
447 result.X = vector.X / scale.X;
448 result.Y = vector.Y / scale.Y;
449 result.Z = vector.Z / scale.Z;
450 result.W = vector.W / scale.W;
454 /// Calculate the component-wise minimum of two vectors
456 /// <param name="a">First operand</param>
457 /// <param name="b">Second operand</param>
458 /// <returns>The component-wise minimum</returns>
459 [Obsolete("Use ComponentMin() instead.")]
460 public static Vector4 Min(Vector4 a, Vector4 b)
462 a.X = a.X < b.X ? a.X : b.X;
463 a.Y = a.Y < b.Y ? a.Y : b.Y;
464 a.Z = a.Z < b.Z ? a.Z : b.Z;
465 a.W = a.W < b.W ? a.W : b.W;
470 /// Calculate the component-wise minimum of two vectors
472 /// <param name="a">First operand</param>
473 /// <param name="b">Second operand</param>
474 /// <param name="result">The component-wise minimum</param>
475 [Obsolete("Use ComponentMin() instead.")]
476 public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result)
478 result.X = a.X < b.X ? a.X : b.X;
479 result.Y = a.Y < b.Y ? a.Y : b.Y;
480 result.Z = a.Z < b.Z ? a.Z : b.Z;
481 result.W = a.W < b.W ? a.W : b.W;
485 /// Calculate the component-wise maximum of two vectors
487 /// <param name="a">First operand</param>
488 /// <param name="b">Second operand</param>
489 /// <returns>The component-wise maximum</returns>
490 [Obsolete("Use ComponentMax() instead.")]
491 public static Vector4 Max(Vector4 a, Vector4 b)
493 a.X = a.X > b.X ? a.X : b.X;
494 a.Y = a.Y > b.Y ? a.Y : b.Y;
495 a.Z = a.Z > b.Z ? a.Z : b.Z;
496 a.W = a.W > b.W ? a.W : b.W;
501 /// Calculate the component-wise maximum of two vectors
503 /// <param name="a">First operand</param>
504 /// <param name="b">Second operand</param>
505 /// <param name="result">The component-wise maximum</param>
506 [Obsolete("Use ComponentMax() instead.")]
507 public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result)
509 result.X = a.X > b.X ? a.X : b.X;
510 result.Y = a.Y > b.Y ? a.Y : b.Y;
511 result.Z = a.Z > b.Z ? a.Z : b.Z;
512 result.W = a.W > b.W ? a.W : b.W;
516 /// Returns a vector created from the smallest of the corresponding components of the given vectors.
518 /// <param name="a">First operand</param>
519 /// <param name="b">Second operand</param>
520 /// <returns>The component-wise minimum</returns>
521 public static Vector4 ComponentMin(Vector4 a, Vector4 b)
523 a.X = a.X < b.X ? a.X : b.X;
524 a.Y = a.Y < b.Y ? a.Y : b.Y;
525 a.Z = a.Z < b.Z ? a.Z : b.Z;
526 a.W = a.W < b.W ? a.W : b.W;
531 /// Returns a vector created from the smallest of the corresponding components of the given vectors.
533 /// <param name="a">First operand</param>
534 /// <param name="b">Second operand</param>
535 /// <param name="result">The component-wise minimum</param>
536 public static void ComponentMin(ref Vector4 a, ref Vector4 b, out Vector4 result)
538 result.X = a.X < b.X ? a.X : b.X;
539 result.Y = a.Y < b.Y ? a.Y : b.Y;
540 result.Z = a.Z < b.Z ? a.Z : b.Z;
541 result.W = a.W < b.W ? a.W : b.W;
545 /// Returns a vector created from the largest of the corresponding components of the given vectors.
547 /// <param name="a">First operand</param>
548 /// <param name="b">Second operand</param>
549 /// <returns>The component-wise maximum</returns>
550 public static Vector4 ComponentMax(Vector4 a, Vector4 b)
552 a.X = a.X > b.X ? a.X : b.X;
553 a.Y = a.Y > b.Y ? a.Y : b.Y;
554 a.Z = a.Z > b.Z ? a.Z : b.Z;
555 a.W = a.W > b.W ? a.W : b.W;
560 /// Returns a vector created from the largest of the corresponding components of the given vectors.
562 /// <param name="a">First operand</param>
563 /// <param name="b">Second operand</param>
564 /// <param name="result">The component-wise maximum</param>
565 public static void ComponentMax(ref Vector4 a, ref Vector4 b, out Vector4 result)
567 result.X = a.X > b.X ? a.X : b.X;
568 result.Y = a.Y > b.Y ? a.Y : b.Y;
569 result.Z = a.Z > b.Z ? a.Z : b.Z;
570 result.W = a.W > b.W ? a.W : b.W;
574 /// Returns the Vector4 with the minimum magnitude. If the magnitudes are equal, the second vector
577 /// <param name="left">Left operand</param>
578 /// <param name="right">Right operand</param>
579 /// <returns>The minimum Vector4</returns>
580 public static Vector4 MagnitudeMin(Vector4 left, Vector4 right)
582 return left.LengthSquared < right.LengthSquared ? left : right;
586 /// Returns the Vector4 with the minimum magnitude. If the magnitudes are equal, the second vector
589 /// <param name="left">Left operand</param>
590 /// <param name="right">Right operand</param>
591 /// <param name="result">The magnitude-wise minimum</param>
592 /// <returns>The minimum Vector4</returns>
593 public static void MagnitudeMin(ref Vector4 left, ref Vector4 right, out Vector4 result)
595 result = left.LengthSquared < right.LengthSquared ? left : right;
599 /// Returns the Vector4 with the maximum magnitude. If the magnitudes are equal, the first vector
602 /// <param name="left">Left operand</param>
603 /// <param name="right">Right operand</param>
604 /// <returns>The maximum Vector4</returns>
605 public static Vector4 MagnitudeMax(Vector4 left, Vector4 right)
607 return left.LengthSquared >= right.LengthSquared ? left : right;
611 /// Returns the Vector4 with the maximum magnitude. If the magnitudes are equal, the first vector
614 /// <param name="left">Left operand</param>
615 /// <param name="right">Right operand</param>
616 /// <param name="result">The magnitude-wise maximum</param>
617 /// <returns>The maximum Vector4</returns>
618 public static void MagnitudeMax(ref Vector4 left, ref Vector4 right, out Vector4 result)
620 result = left.LengthSquared >= right.LengthSquared ? left : right;
624 /// Clamp a vector to the given minimum and maximum vectors
626 /// <param name="vec">Input vector</param>
627 /// <param name="min">Minimum vector</param>
628 /// <param name="max">Maximum vector</param>
629 /// <returns>The clamped vector</returns>
630 public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max)
632 vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
633 vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
634 vec.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
635 vec.W = vec.W < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
640 /// Clamp a vector to the given minimum and maximum vectors
642 /// <param name="vec">Input vector</param>
643 /// <param name="min">Minimum vector</param>
644 /// <param name="max">Maximum vector</param>
645 /// <param name="result">The clamped vector</param>
646 public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result)
648 result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
649 result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
650 result.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z;
651 result.W = vec.W < min.W ? min.W : vec.W > max.W ? max.W : vec.W;
655 /// Scale a vector to unit length
657 /// <param name="vec">The input vector</param>
658 /// <returns>The normalized vector</returns>
659 public static Vector4 Normalize(Vector4 vec)
661 float scale = 1.0f / vec.Length;
670 /// Scale a vector to unit length
672 /// <param name="vec">The input vector</param>
673 /// <param name="result">The normalized vector</param>
674 public static void Normalize(ref Vector4 vec, out Vector4 result)
676 float scale = 1.0f / vec.Length;
677 result.X = vec.X * scale;
678 result.Y = vec.Y * scale;
679 result.Z = vec.Z * scale;
680 result.W = vec.W * scale;
684 /// Scale a vector to approximately unit length
686 /// <param name="vec">The input vector</param>
687 /// <returns>The normalized vector</returns>
688 public static Vector4 NormalizeFast(Vector4 vec)
690 float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
699 /// Scale a vector to approximately unit length
701 /// <param name="vec">The input vector</param>
702 /// <param name="result">The normalized vector</param>
703 public static void NormalizeFast(ref Vector4 vec, out Vector4 result)
705 float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W);
706 result.X = vec.X * scale;
707 result.Y = vec.Y * scale;
708 result.Z = vec.Z * scale;
709 result.W = vec.W * scale;
713 /// Calculate the dot product of two vectors
715 /// <param name="left">First operand</param>
716 /// <param name="right">Second operand</param>
717 /// <returns>The dot product of the two inputs</returns>
718 public static float Dot(Vector4 left, Vector4 right)
720 return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
724 /// Calculate the dot product of two vectors
726 /// <param name="left">First operand</param>
727 /// <param name="right">Second operand</param>
728 /// <param name="result">The dot product of the two inputs</param>
729 public static void Dot(ref Vector4 left, ref Vector4 right, out float result)
731 result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
735 /// Returns a new Vector that is the linear blend of the 2 given Vectors
737 /// <param name="a">First input vector</param>
738 /// <param name="b">Second input vector</param>
739 /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
740 /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
741 public static Vector4 Lerp(Vector4 a, Vector4 b, float blend)
743 a.X = blend * (b.X - a.X) + a.X;
744 a.Y = blend * (b.Y - a.Y) + a.Y;
745 a.Z = blend * (b.Z - a.Z) + a.Z;
746 a.W = blend * (b.W - a.W) + a.W;
751 /// Returns a new Vector that is the linear blend of the 2 given Vectors
753 /// <param name="a">First input vector</param>
754 /// <param name="b">Second input vector</param>
755 /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
756 /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
757 public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result)
759 result.X = blend * (b.X - a.X) + a.X;
760 result.Y = blend * (b.Y - a.Y) + a.Y;
761 result.Z = blend * (b.Z - a.Z) + a.Z;
762 result.W = blend * (b.W - a.W) + a.W;
766 /// Interpolate 3 Vectors using Barycentric coordinates
768 /// <param name="a">First input Vector</param>
769 /// <param name="b">Second input Vector</param>
770 /// <param name="c">Third input Vector</param>
771 /// <param name="u">First Barycentric Coordinate</param>
772 /// <param name="v">Second Barycentric Coordinate</param>
773 /// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
774 public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v)
776 return a + u * (b - a) + v * (c - a);
779 /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
780 /// <param name="a">First input Vector.</param>
781 /// <param name="b">Second input Vector.</param>
782 /// <param name="c">Third input Vector.</param>
783 /// <param name="u">First Barycentric Coordinate.</param>
784 /// <param name="v">Second Barycentric Coordinate.</param>
785 /// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
786 public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result)
790 Vector4 temp = b; // copy
791 Subtract(ref temp, ref a, out temp);
792 Multiply(ref temp, u, out temp);
793 Add(ref result, ref temp, out result);
796 Subtract(ref temp, ref a, out temp);
797 Multiply(ref temp, v, out temp);
798 Add(ref result, ref temp, out result);
801 /// <summary>Transform a Vector by the given Matrix</summary>
802 /// <param name="vec">The vector to transform</param>
803 /// <param name="mat">The desired transformation</param>
804 /// <returns>The transformed vector</returns>
805 public static Vector4 Transform(Vector4 vec, Matrix4 mat)
808 Transform(ref vec, ref mat, out result);
812 /// <summary>Transform a Vector by the given Matrix</summary>
813 /// <param name="vec">The vector to transform</param>
814 /// <param name="mat">The desired transformation</param>
815 /// <param name="result">The transformed vector</param>
816 public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result)
818 result = new Vector4(
819 vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X,
820 vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y,
821 vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z,
822 vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W);
826 /// Transforms a vector by a quaternion rotation.
828 /// <param name="vec">The vector to transform.</param>
829 /// <param name="quat">The quaternion to rotate the vector by.</param>
830 /// <returns>The result of the operation.</returns>
831 public static Vector4 Transform(Vector4 vec, Quaternion quat)
834 Transform(ref vec, ref quat, out result);
839 /// Transforms a vector by a quaternion rotation.
841 /// <param name="vec">The vector to transform.</param>
842 /// <param name="quat">The quaternion to rotate the vector by.</param>
843 /// <param name="result">The result of the operation.</param>
844 public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result)
846 Quaternion v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W), i, t;
847 Quaternion.Invert(ref quat, out i);
848 Quaternion.Multiply(ref quat, ref v, out t);
849 Quaternion.Multiply(ref t, ref i, out v);
857 /// <summary>Transform a Vector by the given Matrix using right-handed notation</summary>
858 /// <param name="mat">The desired transformation</param>
859 /// <param name="vec">The vector to transform</param>
860 public static Vector4 Transform(Matrix4 mat, Vector4 vec)
863 Transform(ref mat, ref vec, out result);
867 /// <summary>Transform a Vector by the given Matrix using right-handed notation</summary>
868 /// <param name="mat">The desired transformation</param>
869 /// <param name="vec">The vector to transform</param>
870 /// <param name="result">The transformed vector</param>
871 public static void Transform(ref Matrix4 mat, ref Vector4 vec, out Vector4 result)
873 result = new Vector4(
874 mat.Row0.X * vec.X + mat.Row0.Y * vec.Y + mat.Row0.Z * vec.Z + mat.Row0.W * vec.W,
875 mat.Row1.X * vec.X + mat.Row1.Y * vec.Y + mat.Row1.Z * vec.Z + mat.Row1.W * vec.W,
876 mat.Row2.X * vec.X + mat.Row2.Y * vec.Y + mat.Row2.Z * vec.Z + mat.Row2.W * vec.W,
877 mat.Row3.X * vec.X + mat.Row3.Y * vec.Y + mat.Row3.Z * vec.Z + mat.Row3.W * vec.W);
881 /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance.
884 public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } }
887 /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance.
890 public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } }
893 /// Gets or sets an OpenTK.Vector2 with the X and W components of this instance.
896 public Vector2 Xw { get { return new Vector2(X, W); } set { X = value.X; W = value.Y; } }
899 /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance.
902 public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } }
905 /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance.
908 public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } }
911 /// Gets or sets an OpenTK.Vector2 with the Y and W components of this instance.
914 public Vector2 Yw { get { return new Vector2(Y, W); } set { Y = value.X; W = value.Y; } }
917 /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance.
920 public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } }
923 /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance.
926 public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } }
929 /// Gets an OpenTK.Vector2 with the Z and W components of this instance.
932 public Vector2 Zw { get { return new Vector2(Z, W); } set { Z = value.X; W = value.Y; } }
935 /// Gets or sets an OpenTK.Vector2 with the W and X components of this instance.
938 public Vector2 Wx { get { return new Vector2(W, X); } set { W = value.X; X = value.Y; } }
941 /// Gets or sets an OpenTK.Vector2 with the W and Y components of this instance.
944 public Vector2 Wy { get { return new Vector2(W, Y); } set { W = value.X; Y = value.Y; } }
947 /// Gets or sets an OpenTK.Vector2 with the W and Z components of this instance.
950 public Vector2 Wz { get { return new Vector2(W, Z); } set { W = value.X; Z = value.Y; } }
953 /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
956 public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } }
959 /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance.
962 public Vector3 Xyw { get { return new Vector3(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } }
965 /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance.
968 public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } }
971 /// Gets or sets an OpenTK.Vector3 with the X, Z, and W components of this instance.
974 public Vector3 Xzw { get { return new Vector3(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } }
977 /// Gets or sets an OpenTK.Vector3 with the X, W, and Y components of this instance.
980 public Vector3 Xwy { get { return new Vector3(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } }
983 /// Gets or sets an OpenTK.Vector3 with the X, W, and Z components of this instance.
986 public Vector3 Xwz { get { return new Vector3(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } }
989 /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance.
992 public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } }
995 /// Gets or sets an OpenTK.Vector3 with the Y, X, and W components of this instance.
998 public Vector3 Yxw { get { return new Vector3(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } }
1001 /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance.
1004 public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } }
1007 /// Gets or sets an OpenTK.Vector3 with the Y, Z, and W components of this instance.
1010 public Vector3 Yzw { get { return new Vector3(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } }
1013 /// Gets or sets an OpenTK.Vector3 with the Y, W, and X components of this instance.
1016 public Vector3 Ywx { get { return new Vector3(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } }
1019 /// Gets an OpenTK.Vector3 with the Y, W, and Z components of this instance.
1022 public Vector3 Ywz { get { return new Vector3(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } }
1025 /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance.
1028 public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } }
1031 /// Gets or sets an OpenTK.Vector3 with the Z, X, and W components of this instance.
1034 public Vector3 Zxw { get { return new Vector3(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } }
1037 /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance.
1040 public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } }
1043 /// Gets or sets an OpenTK.Vector3 with the Z, Y, and W components of this instance.
1046 public Vector3 Zyw { get { return new Vector3(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } }
1049 /// Gets or sets an OpenTK.Vector3 with the Z, W, and X components of this instance.
1052 public Vector3 Zwx { get { return new Vector3(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } }
1055 /// Gets or sets an OpenTK.Vector3 with the Z, W, and Y components of this instance.
1058 public Vector3 Zwy { get { return new Vector3(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } }
1061 /// Gets or sets an OpenTK.Vector3 with the W, X, and Y components of this instance.
1064 public Vector3 Wxy { get { return new Vector3(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } }
1067 /// Gets or sets an OpenTK.Vector3 with the W, X, and Z components of this instance.
1070 public Vector3 Wxz { get { return new Vector3(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } }
1073 /// Gets or sets an OpenTK.Vector3 with the W, Y, and X components of this instance.
1076 public Vector3 Wyx { get { return new Vector3(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } }
1079 /// Gets or sets an OpenTK.Vector3 with the W, Y, and Z components of this instance.
1082 public Vector3 Wyz { get { return new Vector3(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } }
1085 /// Gets or sets an OpenTK.Vector3 with the W, Z, and X components of this instance.
1088 public Vector3 Wzx { get { return new Vector3(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } }
1091 /// Gets or sets an OpenTK.Vector3 with the W, Z, and Y components of this instance.
1094 public Vector3 Wzy { get { return new Vector3(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } }
1097 /// Gets or sets an OpenTK.Vector4 with the X, Y, W, and Z components of this instance.
1100 public Vector4 Xywz { get { return new Vector4(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
1103 /// Gets or sets an OpenTK.Vector4 with the X, Z, Y, and W components of this instance.
1106 public Vector4 Xzyw { get { return new Vector4(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
1109 /// Gets or sets an OpenTK.Vector4 with the X, Z, W, and Y components of this instance.
1112 public Vector4 Xzwy { get { return new Vector4(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } }
1115 /// Gets or sets an OpenTK.Vector4 with the X, W, Y, and Z components of this instance.
1118 public Vector4 Xwyz { get { return new Vector4(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } }
1121 /// Gets or sets an OpenTK.Vector4 with the X, W, Z, and Y components of this instance.
1124 public Vector4 Xwzy { get { return new Vector4(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
1127 /// Gets or sets an OpenTK.Vector4 with the Y, X, Z, and W components of this instance.
1130 public Vector4 Yxzw { get { return new Vector4(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } }
1133 /// Gets or sets an OpenTK.Vector4 with the Y, X, W, and Z components of this instance.
1136 public Vector4 Yxwz { get { return new Vector4(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } }
1139 /// Gets an OpenTK.Vector4 with the Y, Y, Z, and W components of this instance.
1142 public Vector4 Yyzw { get { return new Vector4(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } }
1145 /// Gets an OpenTK.Vector4 with the Y, Y, W, and Z components of this instance.
1148 public Vector4 Yywz { get { return new Vector4(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } }
1151 /// Gets or sets an OpenTK.Vector4 with the Y, Z, X, and W components of this instance.
1154 public Vector4 Yzxw { get { return new Vector4(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } }
1157 /// Gets or sets an OpenTK.Vector4 with the Y, Z, W, and X components of this instance.
1160 public Vector4 Yzwx { get { return new Vector4(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } }
1163 /// Gets or sets an OpenTK.Vector4 with the Y, W, X, and Z components of this instance.
1166 public Vector4 Ywxz { get { return new Vector4(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } }
1169 /// Gets or sets an OpenTK.Vector4 with the Y, W, Z, and X components of this instance.
1172 public Vector4 Ywzx { get { return new Vector4(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } }
1175 /// Gets or sets an OpenTK.Vector4 with the Z, X, Y, and Z components of this instance.
1178 public Vector4 Zxyw { get { return new Vector4(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } }
1181 /// Gets or sets an OpenTK.Vector4 with the Z, X, W, and Y components of this instance.
1184 public Vector4 Zxwy { get { return new Vector4(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } }
1187 /// Gets or sets an OpenTK.Vector4 with the Z, Y, X, and W components of this instance.
1190 public Vector4 Zyxw { get { return new Vector4(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } }
1193 /// Gets or sets an OpenTK.Vector4 with the Z, Y, W, and X components of this instance.
1196 public Vector4 Zywx { get { return new Vector4(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } }
1199 /// Gets or sets an OpenTK.Vector4 with the Z, W, X, and Y components of this instance.
1202 public Vector4 Zwxy { get { return new Vector4(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } }
1205 /// Gets or sets an OpenTK.Vector4 with the Z, W, Y, and X components of this instance.
1208 public Vector4 Zwyx { get { return new Vector4(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } }
1211 /// Gets an OpenTK.Vector4 with the Z, W, Z, and Y components of this instance.
1214 public Vector4 Zwzy { get { return new Vector4(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } }
1217 /// Gets or sets an OpenTK.Vector4 with the W, X, Y, and Z components of this instance.
1220 public Vector4 Wxyz { get { return new Vector4(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } }
1223 /// Gets or sets an OpenTK.Vector4 with the W, X, Z, and Y components of this instance.
1226 public Vector4 Wxzy { get { return new Vector4(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } }
1229 /// Gets or sets an OpenTK.Vector4 with the W, Y, X, and Z components of this instance.
1232 public Vector4 Wyxz { get { return new Vector4(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } }
1235 /// Gets or sets an OpenTK.Vector4 with the W, Y, Z, and X components of this instance.
1238 public Vector4 Wyzx { get { return new Vector4(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } }
1241 /// Gets or sets an OpenTK.Vector4 with the W, Z, X, and Y components of this instance.
1244 public Vector4 Wzxy { get { return new Vector4(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } }
1247 /// Gets or sets an OpenTK.Vector4 with the W, Z, Y, and X components of this instance.
1250 public Vector4 Wzyx { get { return new Vector4(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } }
1253 /// Gets an OpenTK.Vector4 with the W, Z, Y, and W components of this instance.
1256 public Vector4 Wzyw { get { return new Vector4(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } }
1259 /// Adds two instances.
1261 /// <param name="left">The first instance.</param>
1262 /// <param name="right">The second instance.</param>
1263 /// <returns>The result of the calculation.</returns>
1264 public static Vector4 operator +(Vector4 left, Vector4 right)
1274 /// Subtracts two instances.
1276 /// <param name="left">The first instance.</param>
1277 /// <param name="right">The second instance.</param>
1278 /// <returns>The result of the calculation.</returns>
1279 public static Vector4 operator -(Vector4 left, Vector4 right)
1289 /// Negates an instance.
1291 /// <param name="vec">The instance.</param>
1292 /// <returns>The result of the calculation.</returns>
1293 public static Vector4 operator -(Vector4 vec)
1303 /// Multiplies an instance by a scalar.
1305 /// <param name="vec">The instance.</param>
1306 /// <param name="scale">The scalar.</param>
1307 /// <returns>The result of the calculation.</returns>
1308 public static Vector4 operator *(Vector4 vec, float scale)
1318 /// Multiplies an instance by a scalar.
1320 /// <param name="scale">The scalar.</param>
1321 /// <param name="vec">The instance.</param>
1322 /// <returns>The result of the calculation.</returns>
1323 public static Vector4 operator *(float scale, Vector4 vec)
1333 /// Component-wise multiplication between the specified instance by a scale vector.
1335 /// <param name="scale">Left operand.</param>
1336 /// <param name="vec">Right operand.</param>
1337 /// <returns>Result of multiplication.</returns>
1338 public static Vector4 operator *(Vector4 vec, Vector4 scale)
1348 /// Transform a Vector by the given Matrix.
1350 /// <param name="vec">The vector to transform</param>
1351 /// <param name="mat">The desired transformation</param>
1352 /// <returns>The transformed vector</returns>
1353 public static Vector4 operator *(Vector4 vec, Matrix4 mat)
1356 Vector4.Transform(ref vec, ref mat, out result);
1361 /// Transform a Vector by the given Matrix using right-handed notation
1363 /// <param name="mat">The desired transformation</param>
1364 /// <param name="vec">The vector to transform</param>
1365 /// <returns>The transformed vector</returns>
1366 public static Vector4 operator *(Matrix4 mat, Vector4 vec)
1369 Vector4.Transform(ref mat, ref vec, out result);
1374 /// Transforms a vector by a quaternion rotation.
1376 /// <param name="quat">The quaternion to rotate the vector by.</param>
1377 /// <param name="vec">The vector to transform.</param>
1378 /// <returns>The transformed vector</returns>
1379 public static Vector4 operator *(Quaternion quat, Vector4 vec)
1382 Vector4.Transform(ref vec, ref quat, out result);
1387 /// Divides an instance by a scalar.
1389 /// <param name="vec">The instance.</param>
1390 /// <param name="scale">The scalar.</param>
1391 /// <returns>The result of the calculation.</returns>
1392 public static Vector4 operator /(Vector4 vec, float scale)
1402 /// Compares two instances for equality.
1404 /// <param name="left">The first instance.</param>
1405 /// <param name="right">The second instance.</param>
1406 /// <returns>True, if left equals right; false otherwise.</returns>
1407 public static bool operator ==(Vector4 left, Vector4 right)
1409 return left.Equals(right);
1413 /// Compares two instances for inequality.
1415 /// <param name="left">The first instance.</param>
1416 /// <param name="right">The second instance.</param>
1417 /// <returns>True, if left does not equa lright; false otherwise.</returns>
1418 public static bool operator !=(Vector4 left, Vector4 right)
1420 return !left.Equals(right);
1424 /// Returns a pointer to the first element of the specified instance.
1426 /// <param name="v">The instance.</param>
1427 /// <returns>A pointer to the first element of v.</returns>
1428 [CLSCompliant(false)]
1429 unsafe public static explicit operator float*(Vector4 v)
1435 /// Returns a pointer to the first element of the specified instance.
1437 /// <param name="v">The instance.</param>
1438 /// <returns>A pointer to the first element of v.</returns>
1439 public static explicit operator IntPtr(Vector4 v)
1443 return (IntPtr)(&v.X);
1447 private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
1449 /// Returns a System.String that represents the current Vector4.
1451 /// <returns></returns>
1452 public override string ToString()
1454 return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator);
1458 /// Returns the hashcode for this instance.
1460 /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
1461 public override int GetHashCode()
1465 var hashCode = this.X.GetHashCode();
1466 hashCode = (hashCode * 397) ^ this.Y.GetHashCode();
1467 hashCode = (hashCode * 397) ^ this.Z.GetHashCode();
1468 hashCode = (hashCode * 397) ^ this.W.GetHashCode();
1474 /// Indicates whether this instance and a specified object are equal.
1476 /// <param name="obj">The object to compare to.</param>
1477 /// <returns>True if the instances are equal; false otherwise.</returns>
1478 public override bool Equals(object obj)
1480 if (!(obj is Vector4))
1485 return this.Equals((Vector4)obj);
1488 /// <summary>Indicates whether the current vector is equal to another vector.</summary>
1489 /// <param name="other">A vector to compare with this vector.</param>
1490 /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
1491 public bool Equals(Vector4 other)