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 2D vector using two double-precision floating-point numbers.</summary>
31 [StructLayout(LayoutKind.Sequential)]
32 public struct Vector2d : IEquatable<Vector2d>
34 /// <summary>The X coordinate of this instance.</summary>
37 /// <summary>The Y coordinate of this instance.</summary>
41 /// Defines a unit-length Vector2d that points towards the X-axis.
43 public static readonly Vector2d UnitX = new Vector2d(1, 0);
46 /// Defines a unit-length Vector2d that points towards the Y-axis.
48 public static readonly Vector2d UnitY = new Vector2d(0, 1);
51 /// Defines a zero-length Vector2d.
53 public static readonly Vector2d Zero = new Vector2d(0, 0);
56 /// Defines an instance with all components set to 1.
58 public static readonly Vector2d One = new Vector2d(1, 1);
61 /// Defines the size of the Vector2d struct in bytes.
63 public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2d());
66 /// Constructs a new instance.
68 /// <param name="value">The value that will initialize this instance.</param>
69 public Vector2d(double value)
75 /// <summary>Constructs left vector with the given coordinates.</summary>
76 /// <param name="x">The X coordinate.</param>
77 /// <param name="y">The Y coordinate.</param>
78 public Vector2d(double x, double y)
85 /// Gets or sets the value at the index of the Vector.
87 public double this[int index] {
97 throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
109 throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
115 /// Gets the length (magnitude) of the vector.
117 /// <seealso cref="LengthSquared"/>
122 return System.Math.Sqrt(X * X + Y * Y);
127 /// Gets the square of the vector length (magnitude).
130 /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
133 /// <see cref="Length"/>
134 public double LengthSquared
138 return X * X + Y * Y;
143 /// Gets the perpendicular vector on the right side of this vector.
145 public Vector2d PerpendicularRight
149 return new Vector2d(Y, -X);
154 /// Gets the perpendicular vector on the left side of this vector.
156 public Vector2d PerpendicularLeft
160 return new Vector2d(-Y, X);
165 /// Returns a copy of the Vector2d scaled to unit length.
167 /// <returns></returns>
168 public Vector2d Normalized()
176 /// Scales the Vector2 to unit length.
178 public void Normalize()
180 double scale = 1.0 / Length;
186 /// Adds two vectors.
188 /// <param name="a">Left operand.</param>
189 /// <param name="b">Right operand.</param>
190 /// <returns>Result of operation.</returns>
191 public static Vector2d Add(Vector2d a, Vector2d b)
193 Add(ref a, ref b, out a);
198 /// Adds two vectors.
200 /// <param name="a">Left operand.</param>
201 /// <param name="b">Right operand.</param>
202 /// <param name="result">Result of operation.</param>
203 public static void Add(ref Vector2d a, ref Vector2d b, out Vector2d result)
205 result.X = a.X + b.X;
206 result.Y = a.Y + b.Y;
210 /// Subtract one Vector from another
212 /// <param name="a">First operand</param>
213 /// <param name="b">Second operand</param>
214 /// <returns>Result of subtraction</returns>
215 public static Vector2d Subtract(Vector2d a, Vector2d b)
217 Subtract(ref a, ref b, out a);
222 /// Subtract one Vector from another
224 /// <param name="a">First operand</param>
225 /// <param name="b">Second operand</param>
226 /// <param name="result">Result of subtraction</param>
227 public static void Subtract(ref Vector2d a, ref Vector2d b, out Vector2d result)
229 result.X = a.X - b.X;
230 result.Y = a.Y - b.Y;
234 /// Multiplies a vector by a scalar.
236 /// <param name="vector">Left operand.</param>
237 /// <param name="scale">Right operand.</param>
238 /// <returns>Result of the operation.</returns>
239 public static Vector2d Multiply(Vector2d vector, double scale)
241 Multiply(ref vector, scale, out vector);
246 /// Multiplies a vector by a scalar.
248 /// <param name="vector">Left operand.</param>
249 /// <param name="scale">Right operand.</param>
250 /// <param name="result">Result of the operation.</param>
251 public static void Multiply(ref Vector2d vector, double scale, out Vector2d result)
253 result.X = vector.X * scale;
254 result.Y = vector.Y * scale;
258 /// Multiplies a vector by the components a vector (scale).
260 /// <param name="vector">Left operand.</param>
261 /// <param name="scale">Right operand.</param>
262 /// <returns>Result of the operation.</returns>
263 public static Vector2d Multiply(Vector2d vector, Vector2d scale)
265 Multiply(ref vector, ref scale, out vector);
270 /// Multiplies a vector by the components of a vector (scale).
272 /// <param name="vector">Left operand.</param>
273 /// <param name="scale">Right operand.</param>
274 /// <param name="result">Result of the operation.</param>
275 public static void Multiply(ref Vector2d vector, ref Vector2d scale, out Vector2d result)
277 result.X = vector.X * scale.X;
278 result.Y = vector.Y * scale.Y;
282 /// Divides a vector by a scalar.
284 /// <param name="vector">Left operand.</param>
285 /// <param name="scale">Right operand.</param>
286 /// <returns>Result of the operation.</returns>
287 public static Vector2d Divide(Vector2d vector, double scale)
289 Divide(ref vector, scale, out vector);
294 /// Divides a vector by a scalar.
296 /// <param name="vector">Left operand.</param>
297 /// <param name="scale">Right operand.</param>
298 /// <param name="result">Result of the operation.</param>
299 public static void Divide(ref Vector2d vector, double scale, out Vector2d result)
301 result.X = vector.X / scale;
302 result.Y = vector.Y / scale;
306 /// Divides a vector by the components of a vector (scale).
308 /// <param name="vector">Left operand.</param>
309 /// <param name="scale">Right operand.</param>
310 /// <returns>Result of the operation.</returns>
311 public static Vector2d Divide(Vector2d vector, Vector2d scale)
313 Divide(ref vector, ref scale, out vector);
318 /// Divide a vector by the components of a vector (scale).
320 /// <param name="vector">Left operand.</param>
321 /// <param name="scale">Right operand.</param>
322 /// <param name="result">Result of the operation.</param>
323 public static void Divide(ref Vector2d vector, ref Vector2d scale, out Vector2d result)
325 result.X = vector.X / scale.X;
326 result.Y = vector.Y / scale.Y;
330 /// Calculate the component-wise minimum of two vectors
332 /// <param name="a">First operand</param>
333 /// <param name="b">Second operand</param>
334 /// <returns>The component-wise minimum</returns>
335 [Obsolete("Use ComponentMin() instead.")]
336 public static Vector2d Min(Vector2d a, Vector2d b)
338 a.X = a.X < b.X ? a.X : b.X;
339 a.Y = a.Y < b.Y ? a.Y : b.Y;
344 /// Calculate the component-wise minimum of two vectors
346 /// <param name="a">First operand</param>
347 /// <param name="b">Second operand</param>
348 /// <param name="result">The component-wise minimum</param>
349 [Obsolete("Use ComponentMin() instead.")]
350 public static void Min(ref Vector2d a, ref Vector2d b, out Vector2d result)
352 result.X = a.X < b.X ? a.X : b.X;
353 result.Y = a.Y < b.Y ? a.Y : b.Y;
357 /// Calculate the component-wise maximum of two vectors
359 /// <param name="a">First operand</param>
360 /// <param name="b">Second operand</param>
361 /// <returns>The component-wise maximum</returns>
362 [Obsolete("Use ComponentMax() instead.")]
363 public static Vector2d Max(Vector2d a, Vector2d b)
365 a.X = a.X > b.X ? a.X : b.X;
366 a.Y = a.Y > b.Y ? a.Y : b.Y;
371 /// Calculate the component-wise maximum of two vectors
373 /// <param name="a">First operand</param>
374 /// <param name="b">Second operand</param>
375 /// <param name="result">The component-wise maximum</param>
376 [Obsolete("Use ComponentMax() instead.")]
377 public static void Max(ref Vector2d a, ref Vector2d b, out Vector2d result)
379 result.X = a.X > b.X ? a.X : b.X;
380 result.Y = a.Y > b.Y ? a.Y : b.Y;
384 /// Returns a vector created from the smallest of the corresponding components of the given vectors.
386 /// <param name="a">First operand</param>
387 /// <param name="b">Second operand</param>
388 /// <returns>The component-wise minimum</returns>
389 public static Vector2d ComponentMin(Vector2d a, Vector2d b)
391 a.X = a.X < b.X ? a.X : b.X;
392 a.Y = a.Y < b.Y ? a.Y : b.Y;
397 /// Returns a vector created from the smallest of the corresponding components of the given vectors.
399 /// <param name="a">First operand</param>
400 /// <param name="b">Second operand</param>
401 /// <param name="result">The component-wise minimum</param>
402 public static void ComponentMin(ref Vector2d a, ref Vector2d b, out Vector2d result)
404 result.X = a.X < b.X ? a.X : b.X;
405 result.Y = a.Y < b.Y ? a.Y : b.Y;
409 /// Returns a vector created from the largest of the corresponding components of the given vectors.
411 /// <param name="a">First operand</param>
412 /// <param name="b">Second operand</param>
413 /// <returns>The component-wise maximum</returns>
414 public static Vector2d ComponentMax(Vector2d a, Vector2d b)
416 a.X = a.X > b.X ? a.X : b.X;
417 a.Y = a.Y > b.Y ? a.Y : b.Y;
422 /// Returns a vector created from the largest of the corresponding components of the given vectors.
424 /// <param name="a">First operand</param>
425 /// <param name="b">Second operand</param>
426 /// <param name="result">The component-wise maximum</param>
427 public static void ComponentMax(ref Vector2d a, ref Vector2d b, out Vector2d result)
429 result.X = a.X > b.X ? a.X : b.X;
430 result.Y = a.Y > b.Y ? a.Y : b.Y;
434 /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the second vector
437 /// <param name="left">Left operand</param>
438 /// <param name="right">Right operand</param>
439 /// <returns>The minimum Vector2d</returns>
440 public static Vector2d MagnitudeMin(Vector2d left, Vector2d right)
442 return left.LengthSquared < right.LengthSquared ? left : right;
446 /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the second vector
449 /// <param name="left">Left operand</param>
450 /// <param name="right">Right operand</param>
451 /// <param name="result">The magnitude-wise minimum</param>
452 /// <returns>The minimum Vector2d</returns>
453 public static void MagnitudeMin(ref Vector2d left, ref Vector2d right, out Vector2d result)
455 result = left.LengthSquared < right.LengthSquared ? left : right;
459 /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the first vector
462 /// <param name="left">Left operand</param>
463 /// <param name="right">Right operand</param>
464 /// <returns>The minimum Vector2d</returns>
465 public static Vector2d MagnitudeMax(Vector2d left, Vector2d right)
467 return left.LengthSquared >= right.LengthSquared ? left : right;
471 /// Returns the Vector2d with the maximum magnitude. If the magnitudes are equal, the first vector
474 /// <param name="left">Left operand</param>
475 /// <param name="right">Right operand</param>
476 /// <param name="result">The magnitude-wise maximum</param>
477 /// <returns>The maximum Vector2d</returns>
478 public static void MagnitudeMax(ref Vector2d left, ref Vector2d right, out Vector2d result)
480 result = left.LengthSquared >= right.LengthSquared ? left : right;
484 /// Clamp a vector to the given minimum and maximum vectors
486 /// <param name="vec">Input vector</param>
487 /// <param name="min">Minimum vector</param>
488 /// <param name="max">Maximum vector</param>
489 /// <returns>The clamped vector</returns>
490 public static Vector2d Clamp(Vector2d vec, Vector2d min, Vector2d max)
492 vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
493 vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
498 /// Clamp a vector to the given minimum and maximum vectors
500 /// <param name="vec">Input vector</param>
501 /// <param name="min">Minimum vector</param>
502 /// <param name="max">Maximum vector</param>
503 /// <param name="result">The clamped vector</param>
504 public static void Clamp(ref Vector2d vec, ref Vector2d min, ref Vector2d max, out Vector2d result)
506 result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
507 result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
511 /// Compute the euclidean distance between two vectors.
513 /// <param name="vec1">The first vector</param>
514 /// <param name="vec2">The second vector</param>
515 /// <returns>The distance</returns>
516 public static double Distance(Vector2d vec1, Vector2d vec2)
519 Distance(ref vec1, ref vec2, out result);
524 /// Compute the euclidean distance between two vectors.
526 /// <param name="vec1">The first vector</param>
527 /// <param name="vec2">The second vector</param>
528 /// <param name="result">The distance</param>
529 public static void Distance(ref Vector2d vec1, ref Vector2d vec2, out double result)
531 result = Math.Sqrt((vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y));
535 /// Compute the squared euclidean distance between two vectors.
537 /// <param name="vec1">The first vector</param>
538 /// <param name="vec2">The second vector</param>
539 /// <returns>The squared distance</returns>
540 public static double DistanceSquared(Vector2d vec1, Vector2d vec2)
543 DistanceSquared(ref vec1, ref vec2, out result);
548 /// Compute the squared euclidean distance between two vectors.
550 /// <param name="vec1">The first vector</param>
551 /// <param name="vec2">The second vector</param>
552 /// <param name="result">The squared distance</param>
553 public static void DistanceSquared(ref Vector2d vec1, ref Vector2d vec2, out double result)
555 result = (vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y);
559 /// Scale a vector to unit length
561 /// <param name="vec">The input vector</param>
562 /// <returns>The normalized vector</returns>
563 public static Vector2d Normalize(Vector2d vec)
565 double scale = 1.0 / vec.Length;
572 /// Scale a vector to unit length
574 /// <param name="vec">The input vector</param>
575 /// <param name="result">The normalized vector</param>
576 public static void Normalize(ref Vector2d vec, out Vector2d result)
578 double scale = 1.0 / vec.Length;
579 result.X = vec.X * scale;
580 result.Y = vec.Y * scale;
584 /// Scale a vector to approximately unit length
586 /// <param name="vec">The input vector</param>
587 /// <returns>The normalized vector</returns>
588 public static Vector2d NormalizeFast(Vector2d vec)
590 double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
597 /// Scale a vector to approximately unit length
599 /// <param name="vec">The input vector</param>
600 /// <param name="result">The normalized vector</param>
601 public static void NormalizeFast(ref Vector2d vec, out Vector2d result)
603 double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
604 result.X = vec.X * scale;
605 result.Y = vec.Y * scale;
609 /// Calculate the dot (scalar) product of two vectors
611 /// <param name="left">First operand</param>
612 /// <param name="right">Second operand</param>
613 /// <returns>The dot product of the two inputs</returns>
614 public static double Dot(Vector2d left, Vector2d right)
616 return left.X * right.X + left.Y * right.Y;
620 /// Calculate the dot (scalar) product of two vectors
622 /// <param name="left">First operand</param>
623 /// <param name="right">Second operand</param>
624 /// <param name="result">The dot product of the two inputs</param>
625 public static void Dot(ref Vector2d left, ref Vector2d right, out double result)
627 result = left.X * right.X + left.Y * right.Y;
631 /// Returns a new Vector that is the linear blend of the 2 given Vectors
633 /// <param name="a">First input vector</param>
634 /// <param name="b">Second input vector</param>
635 /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
636 /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
637 public static Vector2d Lerp(Vector2d a, Vector2d b, double blend)
639 a.X = blend * (b.X - a.X) + a.X;
640 a.Y = blend * (b.Y - a.Y) + a.Y;
645 /// Returns a new Vector that is the linear blend of the 2 given Vectors
647 /// <param name="a">First input vector</param>
648 /// <param name="b">Second input vector</param>
649 /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
650 /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
651 public static void Lerp(ref Vector2d a, ref Vector2d b, double blend, out Vector2d result)
653 result.X = blend * (b.X - a.X) + a.X;
654 result.Y = blend * (b.Y - a.Y) + a.Y;
658 /// Interpolate 3 Vectors using Barycentric coordinates
660 /// <param name="a">First input Vector</param>
661 /// <param name="b">Second input Vector</param>
662 /// <param name="c">Third input Vector</param>
663 /// <param name="u">First Barycentric Coordinate</param>
664 /// <param name="v">Second Barycentric Coordinate</param>
665 /// <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>
666 public static Vector2d BaryCentric(Vector2d a, Vector2d b, Vector2d c, double u, double v)
668 return a + u * (b - a) + v * (c - a);
671 /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
672 /// <param name="a">First input Vector.</param>
673 /// <param name="b">Second input Vector.</param>
674 /// <param name="c">Third input Vector.</param>
675 /// <param name="u">First Barycentric Coordinate.</param>
676 /// <param name="v">Second Barycentric Coordinate.</param>
677 /// <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>
678 public static void BaryCentric(ref Vector2d a, ref Vector2d b, ref Vector2d c, double u, double v, out Vector2d result)
682 Vector2d temp = b; // copy
683 Subtract(ref temp, ref a, out temp);
684 Multiply(ref temp, u, out temp);
685 Add(ref result, ref temp, out result);
688 Subtract(ref temp, ref a, out temp);
689 Multiply(ref temp, v, out temp);
690 Add(ref result, ref temp, out result);
694 /// Transforms a vector by a quaternion rotation.
696 /// <param name="vec">The vector to transform.</param>
697 /// <param name="quat">The quaternion to rotate the vector by.</param>
698 /// <returns>The result of the operation.</returns>
699 public static Vector2d Transform(Vector2d vec, Quaterniond quat)
702 Transform(ref vec, ref quat, out result);
707 /// Transforms a vector by a quaternion rotation.
709 /// <param name="vec">The vector to transform.</param>
710 /// <param name="quat">The quaternion to rotate the vector by.</param>
711 /// <param name="result">The result of the operation.</param>
712 public static void Transform(ref Vector2d vec, ref Quaterniond quat, out Vector2d result)
714 Quaterniond v = new Quaterniond(vec.X, vec.Y, 0, 0), i, t;
715 Quaterniond.Invert(ref quat, out i);
716 Quaterniond.Multiply(ref quat, ref v, out t);
717 Quaterniond.Multiply(ref t, ref i, out v);
724 /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance.
727 public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } }
730 /// Adds two instances.
732 /// <param name="left">The left instance.</param>
733 /// <param name="right">The right instance.</param>
734 /// <returns>The result of the operation.</returns>
735 public static Vector2d operator +(Vector2d left, Vector2d right)
743 /// Subtracts two instances.
745 /// <param name="left">The left instance.</param>
746 /// <param name="right">The right instance.</param>
747 /// <returns>The result of the operation.</returns>
748 public static Vector2d operator -(Vector2d left, Vector2d right)
756 /// Negates an instance.
758 /// <param name="vec">The instance.</param>
759 /// <returns>The result of the operation.</returns>
760 public static Vector2d operator -(Vector2d vec)
768 /// Multiplies an instance by a scalar.
770 /// <param name="vec">The instance.</param>
771 /// <param name="f">The scalar.</param>
772 /// <returns>The result of the operation.</returns>
773 public static Vector2d operator *(Vector2d vec, double f)
781 /// Multiply an instance by a scalar.
783 /// <param name="f">The scalar.</param>
784 /// <param name="vec">The instance.</param>
785 /// <returns>The result of the operation.</returns>
786 public static Vector2d operator *(double f, Vector2d vec)
794 /// Component-wise multiplication between the specified instance by a scale vector.
796 /// <param name="scale">Left operand.</param>
797 /// <param name="vec">Right operand.</param>
798 /// <returns>Result of multiplication.</returns>
799 public static Vector2d operator *(Vector2d vec, Vector2d scale)
807 /// Divides an instance by a scalar.
809 /// <param name="vec">The instance.</param>
810 /// <param name="f">The scalar.</param>
811 /// <returns>The result of the operation.</returns>
812 public static Vector2d operator /(Vector2d vec, double f)
820 /// Compares two instances for equality.
822 /// <param name="left">The left instance.</param>
823 /// <param name="right">The right instance.</param>
824 /// <returns>True, if both instances are equal; false otherwise.</returns>
825 public static bool operator ==(Vector2d left, Vector2d right)
827 return left.Equals(right);
831 /// Compares two instances for ienquality.
833 /// <param name="left">The left instance.</param>
834 /// <param name="right">The right instance.</param>
835 /// <returns>True, if the instances are not equal; false otherwise.</returns>
836 public static bool operator !=(Vector2d left, Vector2d right)
838 return !left.Equals(right);
841 /// <summary>Converts OpenTK.Vector2 to OpenTK.Vector2d.</summary>
842 /// <param name="v2">The Vector2 to convert.</param>
843 /// <returns>The resulting Vector2d.</returns>
844 public static explicit operator Vector2d(Vector2 v2)
846 return new Vector2d(v2.X, v2.Y);
849 /// <summary>Converts OpenTK.Vector2d to OpenTK.Vector2.</summary>
850 /// <param name="v2d">The Vector2d to convert.</param>
851 /// <returns>The resulting Vector2.</returns>
852 public static explicit operator Vector2(Vector2d v2d)
854 return new Vector2((float)v2d.X, (float)v2d.Y);
857 private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
859 /// Returns a System.String that represents the current instance.
861 /// <returns></returns>
862 public override string ToString()
864 return String.Format("({0}{2} {1})", X, Y, listSeparator);
868 /// Returns the hashcode for this instance.
870 /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
871 public override int GetHashCode()
875 return (this.X.GetHashCode() * 397) ^ this.Y.GetHashCode();
880 /// Indicates whether this instance and a specified object are equal.
882 /// <param name="obj">The object to compare to.</param>
883 /// <returns>True if the instances are equal; false otherwise.</returns>
884 public override bool Equals(object obj)
886 if (!(obj is Vector2d))
891 return this.Equals((Vector2d)obj);
894 /// <summary>Indicates whether the current vector is equal to another vector.</summary>
895 /// <param name="other">A vector to compare with this vector.</param>
896 /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
897 public bool Equals(Vector2d other)