[ElmSharp] Fix SetNextFocusObject issue (#401)
[platform/core/csapi/tizenfx.git] / external / src / OpenTK / OpenTK / Math / Vector2d.cs
1 /*
2 Copyright (c) 2006 - 2008 The Open Toolkit library.
3
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:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
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
20 SOFTWARE.
21 */
22
23 using System;
24 using System.Runtime.InteropServices;
25 using System.Xml.Serialization;
26
27 namespace OpenTK
28 {
29     /// <summary>Represents a 2D vector using two double-precision floating-point numbers.</summary>
30     [Serializable]
31     [StructLayout(LayoutKind.Sequential)]
32     public struct Vector2d : IEquatable<Vector2d>
33     {
34         /// <summary>The X coordinate of this instance.</summary>
35         public double X;
36
37         /// <summary>The Y coordinate of this instance.</summary>
38         public double Y;
39
40         /// <summary>
41         /// Defines a unit-length Vector2d that points towards the X-axis.
42         /// </summary>
43         public static readonly Vector2d UnitX = new Vector2d(1, 0);
44
45         /// <summary>
46         /// Defines a unit-length Vector2d that points towards the Y-axis.
47         /// </summary>
48         public static readonly Vector2d UnitY = new Vector2d(0, 1);
49
50         /// <summary>
51         /// Defines a zero-length Vector2d.
52         /// </summary>
53         public static readonly Vector2d Zero = new Vector2d(0, 0);
54
55         /// <summary>
56         /// Defines an instance with all components set to 1.
57         /// </summary>
58         public static readonly Vector2d One = new Vector2d(1, 1);
59
60         /// <summary>
61         /// Defines the size of the Vector2d struct in bytes.
62         /// </summary>
63         public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2d());
64
65         /// <summary>
66         /// Constructs a new instance.
67         /// </summary>
68         /// <param name="value">The value that will initialize this instance.</param>
69         public Vector2d(double value)
70         {
71             X = value;
72             Y = value;
73         }
74
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)
79         {
80             this.X = x;
81             this.Y = y;
82         }
83
84         /// <summary>
85         /// Gets or sets the value at the index of the Vector.
86         /// </summary>
87         public double this[int index] {
88             get{
89                 if (index == 0)
90                 {
91                     return X;
92                 }
93                 else if (index == 1)
94                 {
95                     return Y;
96                 }
97                 throw new IndexOutOfRangeException("You tried to access this vector at index: " + index);
98             } set{
99                 if (index == 0)
100                 {
101                     X = value;
102                 }
103                 else if (index == 1)
104                 {
105                     Y = value;
106                 }
107                 else
108                 {
109                     throw new IndexOutOfRangeException("You tried to set this vector at index: " + index);
110                 }
111             }
112         }
113
114         /// <summary>
115         /// Gets the length (magnitude) of the vector.
116         /// </summary>
117         /// <seealso cref="LengthSquared"/>
118         public double Length
119         {
120             get
121             {
122                 return System.Math.Sqrt(X * X + Y * Y);
123             }
124         }
125
126         /// <summary>
127         /// Gets the square of the vector length (magnitude).
128         /// </summary>
129         /// <remarks>
130         /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
131         /// for comparisons.
132         /// </remarks>
133         /// <see cref="Length"/>
134         public double LengthSquared
135         {
136             get
137             {
138                 return X * X + Y * Y;
139             }
140         }
141
142         /// <summary>
143         /// Gets the perpendicular vector on the right side of this vector.
144         /// </summary>
145         public Vector2d PerpendicularRight
146         {
147             get
148             {
149                 return new Vector2d(Y, -X);
150             }
151         }
152
153         /// <summary>
154         /// Gets the perpendicular vector on the left side of this vector.
155         /// </summary>
156         public Vector2d PerpendicularLeft
157         {
158             get
159             {
160                 return new Vector2d(-Y, X);
161             }
162         }
163
164         /// <summary>
165         /// Returns a copy of the Vector2d scaled to unit length.
166         /// </summary>
167         /// <returns></returns>
168         public Vector2d Normalized()
169         {
170             Vector2d v = this;
171             v.Normalize();
172             return v;
173         }
174
175         /// <summary>
176         /// Scales the Vector2 to unit length.
177         /// </summary>
178         public void Normalize()
179         {
180             double scale = 1.0 / Length;
181             X *= scale;
182             Y *= scale;
183         }
184
185         /// <summary>
186         /// Adds two vectors.
187         /// </summary>
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)
192         {
193             Add(ref a, ref b, out a);
194             return a;
195         }
196
197         /// <summary>
198         /// Adds two vectors.
199         /// </summary>
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)
204         {
205             result.X = a.X + b.X;
206             result.Y = a.Y + b.Y;
207         }
208
209         /// <summary>
210         /// Subtract one Vector from another
211         /// </summary>
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)
216         {
217             Subtract(ref a, ref b, out a);
218             return a;
219         }
220
221         /// <summary>
222         /// Subtract one Vector from another
223         /// </summary>
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)
228         {
229             result.X = a.X - b.X;
230             result.Y = a.Y - b.Y;
231         }
232
233         /// <summary>
234         /// Multiplies a vector by a scalar.
235         /// </summary>
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)
240         {
241             Multiply(ref vector, scale, out vector);
242             return vector;
243         }
244
245         /// <summary>
246         /// Multiplies a vector by a scalar.
247         /// </summary>
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)
252         {
253             result.X = vector.X * scale;
254             result.Y = vector.Y * scale;
255         }
256
257         /// <summary>
258         /// Multiplies a vector by the components a vector (scale).
259         /// </summary>
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)
264         {
265             Multiply(ref vector, ref scale, out vector);
266             return vector;
267         }
268
269         /// <summary>
270         /// Multiplies a vector by the components of a vector (scale).
271         /// </summary>
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)
276         {
277             result.X = vector.X * scale.X;
278             result.Y = vector.Y * scale.Y;
279         }
280
281         /// <summary>
282         /// Divides a vector by a scalar.
283         /// </summary>
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)
288         {
289             Divide(ref vector, scale, out vector);
290             return vector;
291         }
292
293         /// <summary>
294         /// Divides a vector by a scalar.
295         /// </summary>
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)
300         {
301             result.X = vector.X / scale;
302             result.Y = vector.Y / scale;
303         }
304
305         /// <summary>
306         /// Divides a vector by the components of a vector (scale).
307         /// </summary>
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)
312         {
313             Divide(ref vector, ref scale, out vector);
314             return vector;
315         }
316
317         /// <summary>
318         /// Divide a vector by the components of a vector (scale).
319         /// </summary>
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)
324         {
325             result.X = vector.X / scale.X;
326             result.Y = vector.Y / scale.Y;
327         }
328
329         /// <summary>
330         /// Calculate the component-wise minimum of two vectors
331         /// </summary>
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)
337         {
338             a.X = a.X < b.X ? a.X : b.X;
339             a.Y = a.Y < b.Y ? a.Y : b.Y;
340             return a;
341         }
342
343         /// <summary>
344         /// Calculate the component-wise minimum of two vectors
345         /// </summary>
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)
351         {
352             result.X = a.X < b.X ? a.X : b.X;
353             result.Y = a.Y < b.Y ? a.Y : b.Y;
354         }
355
356         /// <summary>
357         /// Calculate the component-wise maximum of two vectors
358         /// </summary>
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)
364         {
365             a.X = a.X > b.X ? a.X : b.X;
366             a.Y = a.Y > b.Y ? a.Y : b.Y;
367             return a;
368         }
369
370         /// <summary>
371         /// Calculate the component-wise maximum of two vectors
372         /// </summary>
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)
378         {
379             result.X = a.X > b.X ? a.X : b.X;
380             result.Y = a.Y > b.Y ? a.Y : b.Y;
381         }
382
383         /// <summary>
384         /// Returns a vector created from the smallest of the corresponding components of the given vectors.
385         /// </summary>
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)
390         {
391             a.X = a.X < b.X ? a.X : b.X;
392             a.Y = a.Y < b.Y ? a.Y : b.Y;
393             return a;
394         }
395
396         /// <summary>
397         /// Returns a vector created from the smallest of the corresponding components of the given vectors.
398         /// </summary>
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)
403         {
404             result.X = a.X < b.X ? a.X : b.X;
405             result.Y = a.Y < b.Y ? a.Y : b.Y;
406         }
407
408         /// <summary>
409         /// Returns a vector created from the largest of the corresponding components of the given vectors.
410         /// </summary>
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)
415         {
416             a.X = a.X > b.X ? a.X : b.X;
417             a.Y = a.Y > b.Y ? a.Y : b.Y;
418             return a;
419         }
420
421         /// <summary>
422         /// Returns a vector created from the largest of the corresponding components of the given vectors.
423         /// </summary>
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)
428         {
429             result.X = a.X > b.X ? a.X : b.X;
430             result.Y = a.Y > b.Y ? a.Y : b.Y;
431         }
432
433         /// <summary>
434         /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the second vector
435         /// is selected.
436         /// </summary>
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)
441         {
442             return left.LengthSquared < right.LengthSquared ? left : right;
443         }
444
445         /// <summary>
446         /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the second vector
447         /// is selected.
448         /// </summary>
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)
454         {
455             result = left.LengthSquared < right.LengthSquared ? left : right;
456         }
457
458         /// <summary>
459         /// Returns the Vector2d with the minimum magnitude. If the magnitudes are equal, the first vector
460         /// is selected.
461         /// </summary>
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)
466         {
467             return left.LengthSquared >= right.LengthSquared ? left : right;
468         }
469
470         /// <summary>
471         /// Returns the Vector2d with the maximum magnitude. If the magnitudes are equal, the first vector
472         /// is selected.
473         /// </summary>
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)
479         {
480             result = left.LengthSquared >= right.LengthSquared ? left : right;
481         }
482
483         /// <summary>
484         /// Clamp a vector to the given minimum and maximum vectors
485         /// </summary>
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)
491         {
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;
494             return vec;
495         }
496
497         /// <summary>
498         /// Clamp a vector to the given minimum and maximum vectors
499         /// </summary>
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)
505         {
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;
508         }
509
510         /// <summary>
511         /// Compute the euclidean distance between two vectors.
512         /// </summary>
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)
517         {
518             double result;
519             Distance(ref vec1, ref vec2, out result);
520             return result;
521         }
522
523         /// <summary>
524         /// Compute the euclidean distance between two vectors.
525         /// </summary>
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)
530         {
531             result = Math.Sqrt((vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y));
532         }
533
534         /// <summary>
535         /// Compute the squared euclidean distance between two vectors.
536         /// </summary>
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)
541         {
542             double result;
543             DistanceSquared(ref vec1, ref vec2, out result);
544             return result;
545         }
546
547         /// <summary>
548         /// Compute the squared euclidean distance between two vectors.
549         /// </summary>
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)
554         {
555             result = (vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y);
556         }
557
558         /// <summary>
559         /// Scale a vector to unit length
560         /// </summary>
561         /// <param name="vec">The input vector</param>
562         /// <returns>The normalized vector</returns>
563         public static Vector2d Normalize(Vector2d vec)
564         {
565             double scale = 1.0 / vec.Length;
566             vec.X *= scale;
567             vec.Y *= scale;
568             return vec;
569         }
570
571         /// <summary>
572         /// Scale a vector to unit length
573         /// </summary>
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)
577         {
578             double scale = 1.0 / vec.Length;
579             result.X = vec.X * scale;
580             result.Y = vec.Y * scale;
581         }
582
583         /// <summary>
584         /// Scale a vector to approximately unit length
585         /// </summary>
586         /// <param name="vec">The input vector</param>
587         /// <returns>The normalized vector</returns>
588         public static Vector2d NormalizeFast(Vector2d vec)
589         {
590             double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
591             vec.X *= scale;
592             vec.Y *= scale;
593             return vec;
594         }
595
596         /// <summary>
597         /// Scale a vector to approximately unit length
598         /// </summary>
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)
602         {
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;
606         }
607
608         /// <summary>
609         /// Calculate the dot (scalar) product of two vectors
610         /// </summary>
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)
615         {
616             return left.X * right.X + left.Y * right.Y;
617         }
618
619         /// <summary>
620         /// Calculate the dot (scalar) product of two vectors
621         /// </summary>
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)
626         {
627             result = left.X * right.X + left.Y * right.Y;
628         }
629
630         /// <summary>
631         /// Returns a new Vector that is the linear blend of the 2 given Vectors
632         /// </summary>
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)
638         {
639             a.X = blend * (b.X - a.X) + a.X;
640             a.Y = blend * (b.Y - a.Y) + a.Y;
641             return a;
642         }
643
644         /// <summary>
645         /// Returns a new Vector that is the linear blend of the 2 given Vectors
646         /// </summary>
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)
652         {
653             result.X = blend * (b.X - a.X) + a.X;
654             result.Y = blend * (b.Y - a.Y) + a.Y;
655         }
656
657         /// <summary>
658         /// Interpolate 3 Vectors using Barycentric coordinates
659         /// </summary>
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)
667         {
668             return a + u * (b - a) + v * (c - a);
669         }
670
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)
679         {
680             result = a; // copy
681
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);
686
687             temp = c; // copy
688             Subtract(ref temp, ref a, out temp);
689             Multiply(ref temp, v, out temp);
690             Add(ref result, ref temp, out result);
691         }
692
693         /// <summary>
694         /// Transforms a vector by a quaternion rotation.
695         /// </summary>
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)
700         {
701             Vector2d result;
702             Transform(ref vec, ref quat, out result);
703             return result;
704         }
705
706         /// <summary>
707         /// Transforms a vector by a quaternion rotation.
708         /// </summary>
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)
713         {
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);
718
719             result.X = v.X;
720             result.Y = v.Y;
721         }
722
723         /// <summary>
724         /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance.
725         /// </summary>
726         [XmlIgnore]
727         public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } }
728
729         /// <summary>
730         /// Adds two instances.
731         /// </summary>
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)
736         {
737             left.X += right.X;
738             left.Y += right.Y;
739             return left;
740         }
741
742         /// <summary>
743         /// Subtracts two instances.
744         /// </summary>
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)
749         {
750             left.X -= right.X;
751             left.Y -= right.Y;
752             return left;
753         }
754
755         /// <summary>
756         /// Negates an instance.
757         /// </summary>
758         /// <param name="vec">The instance.</param>
759         /// <returns>The result of the operation.</returns>
760         public static Vector2d operator -(Vector2d vec)
761         {
762             vec.X = -vec.X;
763             vec.Y = -vec.Y;
764             return vec;
765         }
766
767         /// <summary>
768         /// Multiplies an instance by a scalar.
769         /// </summary>
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)
774         {
775             vec.X *= f;
776             vec.Y *= f;
777             return vec;
778         }
779
780         /// <summary>
781         /// Multiply an instance by a scalar.
782         /// </summary>
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)
787         {
788             vec.X *= f;
789             vec.Y *= f;
790             return vec;
791         }
792
793         /// <summary>
794         /// Component-wise multiplication between the specified instance by a scale vector.
795         /// </summary>
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)
800         {
801             vec.X *= scale.X;
802             vec.Y *= scale.Y;
803             return vec;
804         }
805
806         /// <summary>
807         /// Divides an instance by a scalar.
808         /// </summary>
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)
813         {
814             vec.X /= f;
815             vec.Y /= f;
816             return vec;
817         }
818
819         /// <summary>
820         /// Compares two instances for equality.
821         /// </summary>
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)
826         {
827             return left.Equals(right);
828         }
829
830         /// <summary>
831         /// Compares two instances for ienquality.
832         /// </summary>
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)
837         {
838             return !left.Equals(right);
839         }
840
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)
845         {
846             return new Vector2d(v2.X, v2.Y);
847         }
848
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)
853         {
854             return new Vector2((float)v2d.X, (float)v2d.Y);
855         }
856
857         private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator;
858         /// <summary>
859         /// Returns a System.String that represents the current instance.
860         /// </summary>
861         /// <returns></returns>
862         public override string ToString()
863         {
864             return String.Format("({0}{2} {1})", X, Y, listSeparator);
865         }
866
867         /// <summary>
868         /// Returns the hashcode for this instance.
869         /// </summary>
870         /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
871         public override int GetHashCode()
872         {
873             unchecked
874             {
875                 return (this.X.GetHashCode() * 397) ^ this.Y.GetHashCode();
876             }
877         }
878
879         /// <summary>
880         /// Indicates whether this instance and a specified object are equal.
881         /// </summary>
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)
885         {
886             if (!(obj is Vector2d))
887             {
888                 return false;
889             }
890
891             return this.Equals((Vector2d)obj);
892         }
893
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)
898         {
899             return
900                 X == other.X &&
901                 Y == other.Y;
902         }
903     }
904 }