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