Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region --- License ---
2
/*
3
Copyright (c) 2006 - 2008 The Open Toolkit library.
4
 
5
Permission is hereby granted, free of charge, to any person obtaining a copy of
6
this software and associated documentation files (the "Software"), to deal in
7
the Software without restriction, including without limitation the rights to
8
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
of the Software, and to permit persons to whom the Software is furnished to do
10
so, subject to the following conditions:
11
 
12
The above copyright notice and this permission notice shall be included in all
13
copies or substantial portions of the Software.
14
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
SOFTWARE.
22
*/
23
#endregion
24
 
25
using System;
26
using System.Runtime.InteropServices;
27
 
28
namespace OpenTK
29
{
30
    /// <summary>Represents a 2D vector using two double-precision floating-point numbers.</summary>
31
    [Serializable]
32
    [StructLayout(LayoutKind.Sequential)]
33
    public struct Vector2d : IEquatable<Vector2d>
34
    {
35
        #region Fields
36
 
37
        /// <summary>The X coordinate of this instance.</summary>
38
        public double X;
39
 
40
        /// <summary>The Y coordinate of this instance.</summary>
41
        public double Y;
42
 
43
        /// <summary>
44
        /// Defines a unit-length Vector2d that points towards the X-axis.
45
        /// </summary>
46
        public static Vector2d UnitX = new Vector2d(1, 0);
47
 
48
        /// <summary>
49
        /// Defines a unit-length Vector2d that points towards the Y-axis.
50
        /// </summary>
51
        public static Vector2d UnitY = new Vector2d(0, 1);
52
 
53
        /// <summary>
54
        /// Defines a zero-length Vector2d.
55
        /// </summary>
56
        public static Vector2d Zero = new Vector2d(0, 0);
57
 
58
        /// <summary>
59
        /// Defines an instance with all components set to 1.
60
        /// </summary>
61
        public static readonly Vector2d One = new Vector2d(1, 1);
62
 
63
        /// <summary>
64
        /// Defines the size of the Vector2d struct in bytes.
65
        /// </summary>
66
        public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2d());
67
 
68
        #endregion
69
 
70
        #region Constructors
71
 
72
        /// <summary>Constructs left vector with the given coordinates.</summary>
73
        /// <param name="x">The X coordinate.</param>
74
        /// <param name="y">The Y coordinate.</param>
75
        public Vector2d(double x, double y)
76
        {
77
            this.X = x;
78
            this.Y = y;
79
        }
80
 
81
        #endregion
82
 
83
        #region Public Members
84
 
85
        #region Instance
86
 
87
        #region public void Add()
88
 
89
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
90
        /// <param name="right">Right operand. This parameter is only read from.</param>
91
        [Obsolete("Use static Add() method instead.")]
92
        public void Add(Vector2d right)
93
        {
94
            this.X += right.X;
95
            this.Y += right.Y;
96
        }
97
 
98
        /// <summary>Add the Vector passed as parameter to this instance.</summary>
99
        /// <param name="right">Right operand. This parameter is only read from.</param>
100
        [CLSCompliant(false)]
101
        [Obsolete("Use static Add() method instead.")]
102
        public void Add(ref Vector2d right)
103
        {
104
            this.X += right.X;
105
            this.Y += right.Y;
106
        }
107
 
108
        #endregion public void Add()
109
 
110
        #region public void Sub()
111
 
112
        /// <summary>Subtract the Vector passed as parameter from this instance.</summary>
113
        /// <param name="right">Right operand. This parameter is only read from.</param>
114
        [Obsolete("Use static Subtract() method instead.")]
115
        public void Sub(Vector2d right)
116
        {
117
            this.X -= right.X;
118
            this.Y -= right.Y;
119
        }
120
 
121
        /// <summary>Subtract the Vector passed as parameter from this instance.</summary>
122
        /// <param name="right">Right operand. This parameter is only read from.</param>
123
        [CLSCompliant(false)]
124
        [Obsolete("Use static Subtract() method instead.")]
125
        public void Sub(ref Vector2d right)
126
        {
127
            this.X -= right.X;
128
            this.Y -= right.Y;
129
        }
130
 
131
        #endregion public void Sub()
132
 
133
        #region public void Mult()
134
 
135
        /// <summary>Multiply this instance by a scalar.</summary>
136
        /// <param name="f">Scalar operand.</param>
137
        [Obsolete("Use static Multiply() method instead.")]
138
        public void Mult(double f)
139
        {
140
            this.X *= f;
141
            this.Y *= f;
142
        }
143
 
144
        #endregion public void Mult()
145
 
146
        #region public void Div()
147
 
148
        /// <summary>Divide this instance by a scalar.</summary>
149
        /// <param name="f">Scalar operand.</param>
150
        [Obsolete("Use static Divide() method instead.")]
151
        public void Div(double f)
152
        {
153
            double mult = 1.0 / f;
154
            this.X *= mult;
155
            this.Y *= mult;
156
        }
157
 
158
        #endregion public void Div()
159
 
160
        #region public double Length
161
 
162
        /// <summary>
163
        /// Gets the length (magnitude) of the vector.
164
        /// </summary>
165
        /// <seealso cref="LengthSquared"/>
166
        public double Length
167
        {
168
            get
169
            {
170
                return System.Math.Sqrt(X * X + Y * Y);
171
            }
172
        }
173
 
174
        #endregion
175
 
176
        #region public double LengthSquared
177
 
178
        /// <summary>
179
        /// Gets the square of the vector length (magnitude).
180
        /// </summary>
181
        /// <remarks>
182
        /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
183
        /// for comparisons.
184
        /// </remarks>
185
        /// <see cref="Length"/>
186
        public double LengthSquared
187
        {
188
            get
189
            {
190
                return X * X + Y * Y;
191
            }
192
        }
193
 
194
        #endregion
195
 
196
        #region public Vector2d PerpendicularRight
197
 
198
        /// <summary>
199
        /// Gets the perpendicular vector on the right side of this vector.
200
        /// </summary>
201
        public Vector2d PerpendicularRight
202
        {
203
            get
204
            {
205
                return new Vector2d(Y, -X);
206
            }
207
        }
208
 
209
        #endregion
210
 
211
        #region public Vector2d PerpendicularLeft
212
 
213
        /// <summary>
214
        /// Gets the perpendicular vector on the left side of this vector.
215
        /// </summary>
216
        public Vector2d PerpendicularLeft
217
        {
218
            get
219
            {
220
                return new Vector2d(-Y, X);
221
            }
222
        }
223
 
224
        #endregion
225
 
226
        #region public void Normalize()
227
 
228
        /// <summary>
229
        /// Scales the Vector2 to unit length.
230
        /// </summary>
231
        public void Normalize()
232
        {
233
            double scale = 1.0 / Length;
234
            X *= scale;
235
            Y *= scale;
236
        }
237
 
238
        #endregion
239
 
240
        #region public void Scale()
241
 
242
        /// <summary>
243
        /// Scales the current Vector2 by the given amounts.
244
        /// </summary>
245
        /// <param name="sx">The scale of the X component.</param>
246
        /// <param name="sy">The scale of the Y component.</param>
247
        [Obsolete("Use static Multiply() method instead.")]
248
        public void Scale(double sx, double sy)
249
        {
250
            X *= sx;
251
            Y *= sy;
252
        }
253
 
254
        /// <summary>Scales this instance by the given parameter.</summary>
255
        /// <param name="scale">The scaling of the individual components.</param>
256
        [Obsolete("Use static Multiply() method instead.")]
257
        public void Scale(Vector2d scale)
258
        {
259
            this.X *= scale.X;
260
            this.Y *= scale.Y;
261
        }
262
 
263
        /// <summary>Scales this instance by the given parameter.</summary>
264
        /// <param name="scale">The scaling of the individual components.</param>
265
        [CLSCompliant(false)]
266
        [Obsolete("Use static Multiply() method instead.")]
267
        public void Scale(ref Vector2d scale)
268
        {
269
            this.X *= scale.X;
270
            this.Y *= scale.Y;
271
        }
272
 
273
        #endregion public void Scale()
274
 
275
        #endregion
276
 
277
        #region Static
278
 
279
        #region Obsolete
280
 
281
        #region Sub
282
 
283
        /// <summary>
284
        /// Subtract one Vector from another
285
        /// </summary>
286
        /// <param name="a">First operand</param>
287
        /// <param name="b">Second operand</param>
288
        /// <returns>Result of subtraction</returns>
289
        [Obsolete("Use static Subtract() method instead.")]
290
        public static Vector2d Sub(Vector2d a, Vector2d b)
291
        {
292
            a.X -= b.X;
293
            a.Y -= b.Y;
294
            return a;
295
        }
296
 
297
        /// <summary>
298
        /// Subtract one Vector from another
299
        /// </summary>
300
        /// <param name="a">First operand</param>
301
        /// <param name="b">Second operand</param>
302
        /// <param name="result">Result of subtraction</param>
303
        [Obsolete("Use static Subtract() method instead.")]
304
        public static void Sub(ref Vector2d a, ref Vector2d b, out Vector2d result)
305
        {
306
            result.X = a.X - b.X;
307
            result.Y = a.Y - b.Y;
308
        }
309
 
310
        #endregion
311
 
312
        #region Mult
313
 
314
        /// <summary>
315
        /// Multiply a vector and a scalar
316
        /// </summary>
317
        /// <param name="a">Vector operand</param>
318
        /// <param name="d">Scalar operand</param>
319
        /// <returns>Result of the multiplication</returns>
320
        [Obsolete("Use static Multiply() method instead.")]
321
        public static Vector2d Mult(Vector2d a, double d)
322
        {
323
            a.X *= d;
324
            a.Y *= d;
325
            return a;
326
        }
327
 
328
        /// <summary>
329
        /// Multiply a vector and a scalar
330
        /// </summary>
331
        /// <param name="a">Vector operand</param>
332
        /// <param name="d">Scalar operand</param>
333
        /// <param name="result">Result of the multiplication</param>
334
        [Obsolete("Use static Multiply() method instead.")]
335
        public static void Mult(ref Vector2d a, double d, out Vector2d result)
336
        {
337
            result.X = a.X * d;
338
            result.Y = a.Y * d;
339
        }
340
 
341
        #endregion
342
 
343
        #region Div
344
 
345
        /// <summary>
346
        /// Divide a vector by a scalar
347
        /// </summary>
348
        /// <param name="a">Vector operand</param>
349
        /// <param name="d">Scalar operand</param>
350
        /// <returns>Result of the division</returns>
351
        [Obsolete("Use static Divide() method instead.")]
352
        public static Vector2d Div(Vector2d a, double d)
353
        {
354
            double mult = 1.0 / d;
355
            a.X *= mult;
356
            a.Y *= mult;
357
            return a;
358
        }
359
 
360
        /// <summary>
361
        /// Divide a vector by a scalar
362
        /// </summary>
363
        /// <param name="a">Vector operand</param>
364
        /// <param name="d">Scalar operand</param>
365
        /// <param name="result">Result of the division</param>
366
        [Obsolete("Use static Divide() method instead.")]
367
        public static void Div(ref Vector2d a, double d, out Vector2d result)
368
        {
369
            double mult = 1.0 / d;
370
            result.X = a.X * mult;
371
            result.Y = a.Y * mult;
372
        }
373
 
374
        #endregion
375
 
376
        #endregion
377
 
378
        #region Add
379
 
380
        /// <summary>
381
        /// Adds two vectors.
382
        /// </summary>
383
        /// <param name="a">Left operand.</param>
384
        /// <param name="b">Right operand.</param>
385
        /// <returns>Result of operation.</returns>
386
        public static Vector2d Add(Vector2d a, Vector2d b)
387
        {
388
            Add(ref a, ref b, out a);
389
            return a;
390
        }
391
 
392
        /// <summary>
393
        /// Adds two vectors.
394
        /// </summary>
395
        /// <param name="a">Left operand.</param>
396
        /// <param name="b">Right operand.</param>
397
        /// <param name="result">Result of operation.</param>
398
        public static void Add(ref Vector2d a, ref Vector2d b, out Vector2d result)
399
        {
400
            result = new Vector2d(a.X + b.X, a.Y + b.Y);
401
        }
402
 
403
        #endregion
404
 
405
        #region Subtract
406
 
407
        /// <summary>
408
        /// Subtract one Vector from another
409
        /// </summary>
410
        /// <param name="a">First operand</param>
411
        /// <param name="b">Second operand</param>
412
        /// <returns>Result of subtraction</returns>
413
        public static Vector2d Subtract(Vector2d a, Vector2d b)
414
        {
415
            Subtract(ref a, ref b, out a);
416
            return a;
417
        }
418
 
419
        /// <summary>
420
        /// Subtract one Vector from another
421
        /// </summary>
422
        /// <param name="a">First operand</param>
423
        /// <param name="b">Second operand</param>
424
        /// <param name="result">Result of subtraction</param>
425
        public static void Subtract(ref Vector2d a, ref Vector2d b, out Vector2d result)
426
        {
427
            result = new Vector2d(a.X - b.X, a.Y - b.Y);
428
        }
429
 
430
        #endregion
431
 
432
        #region Multiply
433
 
434
        /// <summary>
435
        /// Multiplies a vector by a scalar.
436
        /// </summary>
437
        /// <param name="vector">Left operand.</param>
438
        /// <param name="scale">Right operand.</param>
439
        /// <returns>Result of the operation.</returns>
440
        public static Vector2d Multiply(Vector2d vector, double scale)
441
        {
442
            Multiply(ref vector, scale, out vector);
443
            return vector;
444
        }
445
 
446
        /// <summary>
447
        /// Multiplies a vector by a scalar.
448
        /// </summary>
449
        /// <param name="vector">Left operand.</param>
450
        /// <param name="scale">Right operand.</param>
451
        /// <param name="result">Result of the operation.</param>
452
        public static void Multiply(ref Vector2d vector, double scale, out Vector2d result)
453
        {
454
            result = new Vector2d(vector.X * scale, vector.Y * scale);
455
        }
456
 
457
        /// <summary>
458
        /// Multiplies a vector by the components a vector (scale).
459
        /// </summary>
460
        /// <param name="vector">Left operand.</param>
461
        /// <param name="scale">Right operand.</param>
462
        /// <returns>Result of the operation.</returns>
463
        public static Vector2d Multiply(Vector2d vector, Vector2d scale)
464
        {
465
            Multiply(ref vector, ref scale, out vector);
466
            return vector;
467
        }
468
 
469
        /// <summary>
470
        /// Multiplies a vector by the components of a vector (scale).
471
        /// </summary>
472
        /// <param name="vector">Left operand.</param>
473
        /// <param name="scale">Right operand.</param>
474
        /// <param name="result">Result of the operation.</param>
475
        public static void Multiply(ref Vector2d vector, ref Vector2d scale, out Vector2d result)
476
        {
477
            result = new Vector2d(vector.X * scale.X, vector.Y * scale.Y);
478
        }
479
 
480
        #endregion
481
 
482
        #region Divide
483
 
484
        /// <summary>
485
        /// Divides a vector by a scalar.
486
        /// </summary>
487
        /// <param name="vector">Left operand.</param>
488
        /// <param name="scale">Right operand.</param>
489
        /// <returns>Result of the operation.</returns>
490
        public static Vector2d Divide(Vector2d vector, double scale)
491
        {
492
            Divide(ref vector, scale, out vector);
493
            return vector;
494
        }
495
 
496
        /// <summary>
497
        /// Divides a vector by a scalar.
498
        /// </summary>
499
        /// <param name="vector">Left operand.</param>
500
        /// <param name="scale">Right operand.</param>
501
        /// <param name="result">Result of the operation.</param>
502
        public static void Divide(ref Vector2d vector, double scale, out Vector2d result)
503
        {
504
            Multiply(ref vector, 1 / scale, out result);
505
        }
506
 
507
        /// <summary>
508
        /// Divides a vector by the components of a vector (scale).
509
        /// </summary>
510
        /// <param name="vector">Left operand.</param>
511
        /// <param name="scale">Right operand.</param>
512
        /// <returns>Result of the operation.</returns>
513
        public static Vector2d Divide(Vector2d vector, Vector2d scale)
514
        {
515
            Divide(ref vector, ref scale, out vector);
516
            return vector;
517
        }
518
 
519
        /// <summary>
520
        /// Divide a vector by the components of a vector (scale).
521
        /// </summary>
522
        /// <param name="vector">Left operand.</param>
523
        /// <param name="scale">Right operand.</param>
524
        /// <param name="result">Result of the operation.</param>
525
        public static void Divide(ref Vector2d vector, ref Vector2d scale, out Vector2d result)
526
        {
527
            result = new Vector2d(vector.X / scale.X, vector.Y / scale.Y);
528
        }
529
 
530
        #endregion
531
 
532
        #region Min
533
 
534
        /// <summary>
535
        /// Calculate the component-wise minimum of two vectors
536
        /// </summary>
537
        /// <param name="a">First operand</param>
538
        /// <param name="b">Second operand</param>
539
        /// <returns>The component-wise minimum</returns>
540
        public static Vector2d Min(Vector2d a, Vector2d b)
541
        {
542
            a.X = a.X < b.X ? a.X : b.X;
543
            a.Y = a.Y < b.Y ? a.Y : b.Y;
544
            return a;
545
        }
546
 
547
        /// <summary>
548
        /// Calculate the component-wise minimum of two vectors
549
        /// </summary>
550
        /// <param name="a">First operand</param>
551
        /// <param name="b">Second operand</param>
552
        /// <param name="result">The component-wise minimum</param>
553
        public static void Min(ref Vector2d a, ref Vector2d b, out Vector2d result)
554
        {
555
            result.X = a.X < b.X ? a.X : b.X;
556
            result.Y = a.Y < b.Y ? a.Y : b.Y;
557
        }
558
 
559
        #endregion
560
 
561
        #region Max
562
 
563
        /// <summary>
564
        /// Calculate the component-wise maximum of two vectors
565
        /// </summary>
566
        /// <param name="a">First operand</param>
567
        /// <param name="b">Second operand</param>
568
        /// <returns>The component-wise maximum</returns>
569
        public static Vector2d Max(Vector2d a, Vector2d b)
570
        {
571
            a.X = a.X > b.X ? a.X : b.X;
572
            a.Y = a.Y > b.Y ? a.Y : b.Y;
573
            return a;
574
        }
575
 
576
        /// <summary>
577
        /// Calculate the component-wise maximum of two vectors
578
        /// </summary>
579
        /// <param name="a">First operand</param>
580
        /// <param name="b">Second operand</param>
581
        /// <param name="result">The component-wise maximum</param>
582
        public static void Max(ref Vector2d a, ref Vector2d b, out Vector2d result)
583
        {
584
            result.X = a.X > b.X ? a.X : b.X;
585
            result.Y = a.Y > b.Y ? a.Y : b.Y;
586
        }
587
 
588
        #endregion
589
 
590
        #region Clamp
591
 
592
        /// <summary>
593
        /// Clamp a vector to the given minimum and maximum vectors
594
        /// </summary>
595
        /// <param name="vec">Input vector</param>
596
        /// <param name="min">Minimum vector</param>
597
        /// <param name="max">Maximum vector</param>
598
        /// <returns>The clamped vector</returns>
599
        public static Vector2d Clamp(Vector2d vec, Vector2d min, Vector2d max)
600
        {
601
            vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
602
            vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
603
            return vec;
604
        }
605
 
606
        /// <summary>
607
        /// Clamp a vector to the given minimum and maximum vectors
608
        /// </summary>
609
        /// <param name="vec">Input vector</param>
610
        /// <param name="min">Minimum vector</param>
611
        /// <param name="max">Maximum vector</param>
612
        /// <param name="result">The clamped vector</param>
613
        public static void Clamp(ref Vector2d vec, ref Vector2d min, ref Vector2d max, out Vector2d result)
614
        {
615
            result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
616
            result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
617
        }
618
 
619
        #endregion
620
 
621
        #region Normalize
622
 
623
        /// <summary>
624
        /// Scale a vector to unit length
625
        /// </summary>
626
        /// <param name="vec">The input vector</param>
627
        /// <returns>The normalized vector</returns>
628
        public static Vector2d Normalize(Vector2d vec)
629
        {
630
            double scale = 1.0 / vec.Length;
631
            vec.X *= scale;
632
            vec.Y *= scale;
633
            return vec;
634
        }
635
 
636
        /// <summary>
637
        /// Scale a vector to unit length
638
        /// </summary>
639
        /// <param name="vec">The input vector</param>
640
        /// <param name="result">The normalized vector</param>
641
        public static void Normalize(ref Vector2d vec, out Vector2d result)
642
        {
643
            double scale = 1.0 / vec.Length;
644
            result.X = vec.X * scale;
645
            result.Y = vec.Y * scale;
646
        }
647
 
648
        #endregion
649
 
650
        #region NormalizeFast
651
 
652
        /// <summary>
653
        /// Scale a vector to approximately unit length
654
        /// </summary>
655
        /// <param name="vec">The input vector</param>
656
        /// <returns>The normalized vector</returns>
657
        public static Vector2d NormalizeFast(Vector2d vec)
658
        {
659
            double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
660
            vec.X *= scale;
661
            vec.Y *= scale;
662
            return vec;
663
        }
664
 
665
        /// <summary>
666
        /// Scale a vector to approximately unit length
667
        /// </summary>
668
        /// <param name="vec">The input vector</param>
669
        /// <param name="result">The normalized vector</param>
670
        public static void NormalizeFast(ref Vector2d vec, out Vector2d result)
671
        {
672
            double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y);
673
            result.X = vec.X * scale;
674
            result.Y = vec.Y * scale;
675
        }
676
 
677
        #endregion
678
 
679
        #region Dot
680
 
681
        /// <summary>
682
        /// Calculate the dot (scalar) product of two vectors
683
        /// </summary>
684
        /// <param name="left">First operand</param>
685
        /// <param name="right">Second operand</param>
686
        /// <returns>The dot product of the two inputs</returns>
687
        public static double Dot(Vector2d left, Vector2d right)
688
        {
689
            return left.X * right.X + left.Y * right.Y;
690
        }
691
 
692
        /// <summary>
693
        /// Calculate the dot (scalar) product of two vectors
694
        /// </summary>
695
        /// <param name="left">First operand</param>
696
        /// <param name="right">Second operand</param>
697
        /// <param name="result">The dot product of the two inputs</param>
698
        public static void Dot(ref Vector2d left, ref Vector2d right, out double result)
699
        {
700
            result = left.X * right.X + left.Y * right.Y;
701
        }
702
 
703
        #endregion
704
 
705
        #region Lerp
706
 
707
        /// <summary>
708
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
709
        /// </summary>
710
        /// <param name="a">First input vector</param>
711
        /// <param name="b">Second input vector</param>
712
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
713
        /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
714
        public static Vector2d Lerp(Vector2d a, Vector2d b, double blend)
715
        {
716
            a.X = blend * (b.X - a.X) + a.X;
717
            a.Y = blend * (b.Y - a.Y) + a.Y;
718
            return a;
719
        }
720
 
721
        /// <summary>
722
        /// Returns a new Vector that is the linear blend of the 2 given Vectors
723
        /// </summary>
724
        /// <param name="a">First input vector</param>
725
        /// <param name="b">Second input vector</param>
726
        /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
727
        /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
728
        public static void Lerp(ref Vector2d a, ref Vector2d b, double blend, out Vector2d result)
729
        {
730
            result.X = blend * (b.X - a.X) + a.X;
731
            result.Y = blend * (b.Y - a.Y) + a.Y;
732
        }
733
 
734
        #endregion
735
 
736
        #region Barycentric
737
 
738
        /// <summary>
739
        /// Interpolate 3 Vectors using Barycentric coordinates
740
        /// </summary>
741
        /// <param name="a">First input Vector</param>
742
        /// <param name="b">Second input Vector</param>
743
        /// <param name="c">Third input Vector</param>
744
        /// <param name="u">First Barycentric Coordinate</param>
745
        /// <param name="v">Second Barycentric Coordinate</param>
746
        /// <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>
747
        public static Vector2d BaryCentric(Vector2d a, Vector2d b, Vector2d c, double u, double v)
748
        {
749
            return a + u * (b - a) + v * (c - a);
750
        }
751
 
752
        /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
753
        /// <param name="a">First input Vector.</param>
754
        /// <param name="b">Second input Vector.</param>
755
        /// <param name="c">Third input Vector.</param>
756
        /// <param name="u">First Barycentric Coordinate.</param>
757
        /// <param name="v">Second Barycentric Coordinate.</param>
758
        /// <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>
759
        public static void BaryCentric(ref Vector2d a, ref Vector2d b, ref Vector2d c, double u, double v, out Vector2d result)
760
        {
761
            result = a; // copy
762
 
763
            Vector2d temp = b; // copy
764
            Subtract(ref temp, ref a, out temp);
765
            Multiply(ref temp, u, out temp);
766
            Add(ref result, ref temp, out result);
767
 
768
            temp = c; // copy
769
            Subtract(ref temp, ref a, out temp);
770
            Multiply(ref temp, v, out temp);
771
            Add(ref result, ref temp, out result);
772
        }
773
 
774
        #endregion
775
 
776
        #region Transform
777
 
778
        /// <summary>
779
        /// Transforms a vector by a quaternion rotation.
780
        /// </summary>
781
        /// <param name="vec">The vector to transform.</param>
782
        /// <param name="quat">The quaternion to rotate the vector by.</param>
783
        /// <returns>The result of the operation.</returns>
784
        public static Vector2d Transform(Vector2d vec, Quaterniond quat)
785
        {
786
            Vector2d result;
787
            Transform(ref vec, ref quat, out result);
788
            return result;
789
        }
790
 
791
        /// <summary>
792
        /// Transforms a vector by a quaternion rotation.
793
        /// </summary>
794
        /// <param name="vec">The vector to transform.</param>
795
        /// <param name="quat">The quaternion to rotate the vector by.</param>
796
        /// <param name="result">The result of the operation.</param>
797
        public static void Transform(ref Vector2d vec, ref Quaterniond quat, out Vector2d result)
798
        {
799
            Quaterniond v = new Quaterniond(vec.X, vec.Y, 0, 0), i, t;
800
            Quaterniond.Invert(ref quat, out i);
801
            Quaterniond.Multiply(ref quat, ref v, out t);
802
            Quaterniond.Multiply(ref t, ref i, out v);
803
 
804
            result = new Vector2d(v.X, v.Y);
805
        }
806
 
807
        #endregion
808
 
809
        #endregion
810
 
811
        #region Operators
812
 
813
        /// <summary>
814
        /// Adds two instances.
815
        /// </summary>
816
        /// <param name="left">The left instance.</param>
817
        /// <param name="right">The right instance.</param>
818
        /// <returns>The result of the operation.</returns>
819
        public static Vector2d operator +(Vector2d left, Vector2d right)
820
        {
821
            left.X += right.X;
822
            left.Y += right.Y;
823
            return left;
824
        }
825
 
826
        /// <summary>
827
        /// Subtracts two instances.
828
        /// </summary>
829
        /// <param name="left">The left instance.</param>
830
        /// <param name="right">The right instance.</param>
831
        /// <returns>The result of the operation.</returns>
832
        public static Vector2d operator -(Vector2d left, Vector2d right)
833
        {
834
            left.X -= right.X;
835
            left.Y -= right.Y;
836
            return left;
837
        }
838
 
839
        /// <summary>
840
        /// Negates an instance.
841
        /// </summary>
842
        /// <param name="vec">The instance.</param>
843
        /// <returns>The result of the operation.</returns>
844
        public static Vector2d operator -(Vector2d vec)
845
        {
846
            vec.X = -vec.X;
847
            vec.Y = -vec.Y;
848
            return vec;
849
        }
850
 
851
        /// <summary>
852
        /// Multiplies an instance by a scalar.
853
        /// </summary>
854
        /// <param name="vec">The instance.</param>
855
        /// <param name="f">The scalar.</param>
856
        /// <returns>The result of the operation.</returns>
857
        public static Vector2d operator *(Vector2d vec, double f)
858
        {
859
            vec.X *= f;
860
            vec.Y *= f;
861
            return vec;
862
        }
863
 
864
        /// <summary>
865
        /// Multiply an instance by a scalar.
866
        /// </summary>
867
        /// <param name="f">The scalar.</param>
868
        /// <param name="vec">The instance.</param>
869
        /// <returns>The result of the operation.</returns>
870
        public static Vector2d operator *(double f, Vector2d vec)
871
        {
872
            vec.X *= f;
873
            vec.Y *= f;
874
            return vec;
875
        }
876
 
877
        /// <summary>
878
        /// Divides an instance by a scalar.
879
        /// </summary>
880
        /// <param name="vec">The instance.</param>
881
        /// <param name="f">The scalar.</param>
882
        /// <returns>The result of the operation.</returns>
883
        public static Vector2d operator /(Vector2d vec, double f)
884
        {
885
            double mult = 1.0 / f;
886
            vec.X *= mult;
887
            vec.Y *= mult;
888
            return vec;
889
        }
890
 
891
        /// <summary>
892
        /// Compares two instances for equality.
893
        /// </summary>
894
        /// <param name="left">The left instance.</param>
895
        /// <param name="right">The right instance.</param>
896
        /// <returns>True, if both instances are equal; false otherwise.</returns>
897
        public static bool operator ==(Vector2d left, Vector2d right)
898
        {
899
            return left.Equals(right);
900
        }
901
 
902
        /// <summary>
903
        /// Compares two instances for ienquality.
904
        /// </summary>
905
        /// <param name="left">The left instance.</param>
906
        /// <param name="right">The right instance.</param>
907
        /// <returns>True, if the instances are not equal; false otherwise.</returns>
908
        public static bool operator !=(Vector2d left, Vector2d right)
909
        {
910
            return !left.Equals(right);
911
        }
912
 
913
        /// <summary>Converts OpenTK.Vector2 to OpenTK.Vector2d.</summary>
914
        /// <param name="v2">The Vector2 to convert.</param>
915
        /// <returns>The resulting Vector2d.</returns>
916
        public static explicit operator Vector2d(Vector2 v2)
917
        {
918
            return new Vector2d(v2.X, v2.Y);
919
        }
920
 
921
        /// <summary>Converts OpenTK.Vector2d to OpenTK.Vector2.</summary>
922
        /// <param name="v2d">The Vector2d to convert.</param>
923
        /// <returns>The resulting Vector2.</returns>
924
        public static explicit operator Vector2(Vector2d v2d)
925
        {
926
            return new Vector2((float)v2d.X, (float)v2d.Y);
927
        }
928
 
929
        #endregion
930
 
931
        #region Overrides
932
 
933
        #region public override string ToString()
934
 
935
        /// <summary>
936
        /// Returns a System.String that represents the current instance.
937
        /// </summary>
938
        /// <returns></returns>
939
        public override string ToString()
940
        {
941
            return String.Format("({0}, {1})", X, Y);
942
        }
943
 
944
        #endregion
945
 
946
        #region public override int GetHashCode()
947
 
948
        /// <summary>
949
        /// Returns the hashcode for this instance.
950
        /// </summary>
951
        /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
952
        public override int GetHashCode()
953
        {
954
            return X.GetHashCode() ^ Y.GetHashCode();
955
        }
956
 
957
        #endregion
958
 
959
        #region public override bool Equals(object obj)
960
 
961
        /// <summary>
962
        /// Indicates whether this instance and a specified object are equal.
963
        /// </summary>
964
        /// <param name="obj">The object to compare to.</param>
965
        /// <returns>True if the instances are equal; false otherwise.</returns>
966
        public override bool Equals(object obj)
967
        {
968
            if (!(obj is Vector2d))
969
                return false;
970
 
971
            return this.Equals((Vector2d)obj);
972
        }
973
 
974
        #endregion
975
 
976
        #endregion
977
 
978
        #endregion
979
 
980
        #region IEquatable<Vector2d> Members
981
 
982
        /// <summary>Indicates whether the current vector is equal to another vector.</summary>
983
        /// <param name="other">A vector to compare with this vector.</param>
984
        /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
985
        public bool Equals(Vector2d other)
986
        {
987
            return
988
                X == other.X &&
989
                Y == other.Y;
990
        }
991
 
992
        #endregion
993
    }
994
}