1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Globalization;
6 using System.Runtime.InteropServices;
7 using Xunit;
8 
9 namespace System.Numerics.Tests
10 {
11     public class Vector2Tests
12     {
13         [Fact]
Vector2MarshalSizeTest()14         public void Vector2MarshalSizeTest()
15         {
16             Assert.Equal(8, Marshal.SizeOf<Vector2>());
17             Assert.Equal(8, Marshal.SizeOf<Vector2>(new Vector2()));
18         }
19 
20         [Fact]
Vector2CopyToTest()21         public void Vector2CopyToTest()
22         {
23             Vector2 v1 = new Vector2(2.0f, 3.0f);
24 
25             float[] a = new float[3];
26             float[] b = new float[2];
27 
28             Assert.Throws<NullReferenceException>(() => v1.CopyTo(null, 0));
29             Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, -1));
30             Assert.Throws<ArgumentOutOfRangeException>(() => v1.CopyTo(a, a.Length));
31 
32             if (!PlatformDetection.IsNetNative)
33             {
34                AssertExtensions.Throws<ArgumentException>(null, () => v1.CopyTo(a, 2));
35             }
36             else
37             {
38                // The .Net Native code generation optimizer does aggressive optimizations to range checks
39                // which result in an ArgumentOutOfRangeException exception being thrown at runtime.
40                Assert.ThrowsAny<ArgumentException>(() => v1.CopyTo(a, 2));
41             }
42 
43             v1.CopyTo(a, 1);
44             v1.CopyTo(b);
45             Assert.Equal(0.0, a[0]);
46             Assert.Equal(2.0, a[1]);
47             Assert.Equal(3.0, a[2]);
48             Assert.Equal(2.0, b[0]);
49             Assert.Equal(3.0, b[1]);
50         }
51 
52         [Fact]
Vector2GetHashCodeTest()53         public void Vector2GetHashCodeTest()
54         {
55             Vector2 v1 = new Vector2(2.0f, 3.0f);
56             Vector2 v2 = new Vector2(2.0f, 3.0f);
57             Vector2 v3 = new Vector2(3.0f, 2.0f);
58             Assert.Equal(v1.GetHashCode(), v1.GetHashCode());
59             Assert.Equal(v1.GetHashCode(), v2.GetHashCode());
60             Assert.NotEqual(v1.GetHashCode(), v3.GetHashCode());
61             Vector2 v4 = new Vector2(0.0f, 0.0f);
62             Vector2 v6 = new Vector2(1.0f, 0.0f);
63             Vector2 v7 = new Vector2(0.0f, 1.0f);
64             Vector2 v8 = new Vector2(1.0f, 1.0f);
65             Assert.NotEqual(v4.GetHashCode(), v6.GetHashCode());
66             Assert.NotEqual(v4.GetHashCode(), v7.GetHashCode());
67             Assert.NotEqual(v4.GetHashCode(), v8.GetHashCode());
68             Assert.NotEqual(v7.GetHashCode(), v6.GetHashCode());
69             Assert.NotEqual(v8.GetHashCode(), v6.GetHashCode());
70             Assert.NotEqual(v8.GetHashCode(), v7.GetHashCode());
71         }
72 
73         [Fact]
Vector2ToStringTest()74         public void Vector2ToStringTest()
75         {
76             string separator = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator;
77             CultureInfo enUsCultureInfo = new CultureInfo("en-US");
78 
79             Vector2 v1 = new Vector2(2.0f, 3.0f);
80 
81             string v1str = v1.ToString();
82             string expectedv1 = string.Format(CultureInfo.CurrentCulture
83                 , "<{1:G}{0} {2:G}>"
84                 , new object[] { separator, 2, 3 });
85             Assert.Equal(expectedv1, v1str);
86 
87             string v1strformatted = v1.ToString("c", CultureInfo.CurrentCulture);
88             string expectedv1formatted = string.Format(CultureInfo.CurrentCulture
89                 , "<{1:c}{0} {2:c}>"
90                 , new object[] { separator, 2, 3 });
91             Assert.Equal(expectedv1formatted, v1strformatted);
92 
93             string v2strformatted = v1.ToString("c", enUsCultureInfo);
94             string expectedv2formatted = string.Format(enUsCultureInfo
95                 , "<{1:c}{0} {2:c}>"
96                 , new object[] { enUsCultureInfo.NumberFormat.NumberGroupSeparator, 2, 3 });
97             Assert.Equal(expectedv2formatted, v2strformatted);
98 
99             string v3strformatted = v1.ToString("c");
100             string expectedv3formatted = string.Format(CultureInfo.CurrentCulture
101                 , "<{1:c}{0} {2:c}>"
102                 , new object[] { separator, 2, 3 });
103             Assert.Equal(expectedv3formatted, v3strformatted);
104         }
105 
106         // A test for Distance (Vector2f, Vector2f)
107         [Fact]
Vector2DistanceTest()108         public void Vector2DistanceTest()
109         {
110             Vector2 a = new Vector2(1.0f, 2.0f);
111             Vector2 b = new Vector2(3.0f, 4.0f);
112 
113             float expected = (float)System.Math.Sqrt(8);
114             float actual;
115 
116             actual = Vector2.Distance(a, b);
117             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Distance did not return the expected value.");
118         }
119 
120         // A test for Distance (Vector2f, Vector2f)
121         // Distance from the same point
122         [Fact]
Vector2DistanceTest2()123         public void Vector2DistanceTest2()
124         {
125             Vector2 a = new Vector2(1.051f, 2.05f);
126             Vector2 b = new Vector2(1.051f, 2.05f);
127 
128             float actual = Vector2.Distance(a, b);
129             Assert.Equal(0.0f, actual);
130         }
131 
132         // A test for DistanceSquared (Vector2f, Vector2f)
133         [Fact]
Vector2DistanceSquaredTest()134         public void Vector2DistanceSquaredTest()
135         {
136             Vector2 a = new Vector2(1.0f, 2.0f);
137             Vector2 b = new Vector2(3.0f, 4.0f);
138 
139             float expected = 8.0f;
140             float actual;
141 
142             actual = Vector2.DistanceSquared(a, b);
143             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.DistanceSquared did not return the expected value.");
144         }
145 
146         // A test for Dot (Vector2f, Vector2f)
147         [Fact]
Vector2DotTest()148         public void Vector2DotTest()
149         {
150             Vector2 a = new Vector2(1.0f, 2.0f);
151             Vector2 b = new Vector2(3.0f, 4.0f);
152 
153             float expected = 11.0f;
154             float actual;
155 
156             actual = Vector2.Dot(a, b);
157             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Dot did not return the expected value.");
158         }
159 
160         // A test for Dot (Vector2f, Vector2f)
161         // Dot test for perpendicular vector
162         [Fact]
Vector2DotTest1()163         public void Vector2DotTest1()
164         {
165             Vector2 a = new Vector2(1.55f, 1.55f);
166             Vector2 b = new Vector2(-1.55f, 1.55f);
167 
168             float expected = 0.0f;
169             float actual = Vector2.Dot(a, b);
170             Assert.Equal(expected, actual);
171         }
172 
173         // A test for Dot (Vector2f, Vector2f)
174         // Dot test with specail float values
175         [Fact]
Vector2DotTest2()176         public void Vector2DotTest2()
177         {
178             Vector2 a = new Vector2(float.MinValue, float.MinValue);
179             Vector2 b = new Vector2(float.MaxValue, float.MaxValue);
180 
181             float actual = Vector2.Dot(a, b);
182             Assert.True(float.IsNegativeInfinity(actual), "Vector2f.Dot did not return the expected value.");
183         }
184 
185         // A test for Length ()
186         [Fact]
Vector2LengthTest()187         public void Vector2LengthTest()
188         {
189             Vector2 a = new Vector2(2.0f, 4.0f);
190 
191             Vector2 target = a;
192 
193             float expected = (float)System.Math.Sqrt(20);
194             float actual;
195 
196             actual = target.Length();
197 
198             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Length did not return the expected value.");
199         }
200 
201         // A test for Length ()
202         // Length test where length is zero
203         [Fact]
Vector2LengthTest1()204         public void Vector2LengthTest1()
205         {
206             Vector2 target = new Vector2();
207             target.X = 0.0f;
208             target.Y = 0.0f;
209 
210             float expected = 0.0f;
211             float actual;
212 
213             actual = target.Length();
214 
215             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Length did not return the expected value.");
216         }
217 
218         // A test for LengthSquared ()
219         [Fact]
Vector2LengthSquaredTest()220         public void Vector2LengthSquaredTest()
221         {
222             Vector2 a = new Vector2(2.0f, 4.0f);
223 
224             Vector2 target = a;
225 
226             float expected = 20.0f;
227             float actual;
228 
229             actual = target.LengthSquared();
230 
231             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.LengthSquared did not return the expected value.");
232         }
233 
234         // A test for LengthSquared ()
235         // LengthSquared test where the result is zero
236         [Fact]
Vector2LengthSquaredTest1()237         public void Vector2LengthSquaredTest1()
238         {
239             Vector2 a = new Vector2(0.0f, 0.0f);
240 
241             float expected = 0.0f;
242             float actual = a.LengthSquared();
243 
244             Assert.Equal(expected, actual);
245         }
246 
247         // A test for Min (Vector2f, Vector2f)
248         [Fact]
Vector2MinTest()249         public void Vector2MinTest()
250         {
251             Vector2 a = new Vector2(-1.0f, 4.0f);
252             Vector2 b = new Vector2(2.0f, 1.0f);
253 
254             Vector2 expected = new Vector2(-1.0f, 1.0f);
255             Vector2 actual;
256             actual = Vector2.Min(a, b);
257             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Min did not return the expected value.");
258         }
259 
260         [Fact]
Vector2MinMaxCodeCoverageTest()261         public void Vector2MinMaxCodeCoverageTest()
262         {
263             Vector2 min = new Vector2(0, 0);
264             Vector2 max = new Vector2(1, 1);
265             Vector2 actual;
266 
267             // Min.
268             actual = Vector2.Min(min, max);
269             Assert.Equal(actual, min);
270 
271             actual = Vector2.Min(max, min);
272             Assert.Equal(actual, min);
273 
274             // Max.
275             actual = Vector2.Max(min, max);
276             Assert.Equal(actual, max);
277 
278             actual = Vector2.Max(max, min);
279             Assert.Equal(actual, max);
280         }
281 
282         // A test for Max (Vector2f, Vector2f)
283         [Fact]
Vector2MaxTest()284         public void Vector2MaxTest()
285         {
286             Vector2 a = new Vector2(-1.0f, 4.0f);
287             Vector2 b = new Vector2(2.0f, 1.0f);
288 
289             Vector2 expected = new Vector2(2.0f, 4.0f);
290             Vector2 actual;
291             actual = Vector2.Max(a, b);
292             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Max did not return the expected value.");
293         }
294 
295         // A test for Clamp (Vector2f, Vector2f, Vector2f)
296         [Fact]
Vector2ClampTest()297         public void Vector2ClampTest()
298         {
299             Vector2 a = new Vector2(0.5f, 0.3f);
300             Vector2 min = new Vector2(0.0f, 0.1f);
301             Vector2 max = new Vector2(1.0f, 1.1f);
302 
303             // Normal case.
304             // Case N1: specified value is in the range.
305             Vector2 expected = new Vector2(0.5f, 0.3f);
306             Vector2 actual = Vector2.Clamp(a, min, max);
307             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
308             // Normal case.
309             // Case N2: specified value is bigger than max value.
310             a = new Vector2(2.0f, 3.0f);
311             expected = max;
312             actual = Vector2.Clamp(a, min, max);
313             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
314             // Case N3: specified value is smaller than max value.
315             a = new Vector2(-1.0f, -2.0f);
316             expected = min;
317             actual = Vector2.Clamp(a, min, max);
318             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
319             // Case N4: combination case.
320             a = new Vector2(-2.0f, 4.0f);
321             expected = new Vector2(min.X, max.Y);
322             actual = Vector2.Clamp(a, min, max);
323             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
324             // User specified min value is bigger than max value.
325             max = new Vector2(0.0f, 0.1f);
326             min = new Vector2(1.0f, 1.1f);
327 
328             // Case W1: specified value is in the range.
329             a = new Vector2(0.5f, 0.3f);
330             expected = min;
331             actual = Vector2.Clamp(a, min, max);
332             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
333 
334             // Normal case.
335             // Case W2: specified value is bigger than max and min value.
336             a = new Vector2(2.0f, 3.0f);
337             expected = min;
338             actual = Vector2.Clamp(a, min, max);
339             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
340 
341             // Case W3: specified value is smaller than min and max value.
342             a = new Vector2(-1.0f, -2.0f);
343             expected = min;
344             actual = Vector2.Clamp(a, min, max);
345             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Clamp did not return the expected value.");
346         }
347 
348         // A test for Lerp (Vector2f, Vector2f, float)
349         [Fact]
Vector2LerpTest()350         public void Vector2LerpTest()
351         {
352             Vector2 a = new Vector2(1.0f, 2.0f);
353             Vector2 b = new Vector2(3.0f, 4.0f);
354 
355             float t = 0.5f;
356 
357             Vector2 expected = new Vector2(2.0f, 3.0f);
358             Vector2 actual;
359             actual = Vector2.Lerp(a, b, t);
360             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
361         }
362 
363         // A test for Lerp (Vector2f, Vector2f, float)
364         // Lerp test with factor zero
365         [Fact]
Vector2LerpTest1()366         public void Vector2LerpTest1()
367         {
368             Vector2 a = new Vector2(0.0f, 0.0f);
369             Vector2 b = new Vector2(3.18f, 4.25f);
370 
371             float t = 0.0f;
372             Vector2 expected = Vector2.Zero;
373             Vector2 actual = Vector2.Lerp(a, b, t);
374             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
375         }
376 
377         // A test for Lerp (Vector2f, Vector2f, float)
378         // Lerp test with factor one
379         [Fact]
Vector2LerpTest2()380         public void Vector2LerpTest2()
381         {
382             Vector2 a = new Vector2(0.0f, 0.0f);
383             Vector2 b = new Vector2(3.18f, 4.25f);
384 
385             float t = 1.0f;
386             Vector2 expected = new Vector2(3.18f, 4.25f);
387             Vector2 actual = Vector2.Lerp(a, b, t);
388             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
389         }
390 
391         // A test for Lerp (Vector2f, Vector2f, float)
392         // Lerp test with factor > 1
393         [Fact]
Vector2LerpTest3()394         public void Vector2LerpTest3()
395         {
396             Vector2 a = new Vector2(0.0f, 0.0f);
397             Vector2 b = new Vector2(3.18f, 4.25f);
398 
399             float t = 2.0f;
400             Vector2 expected = b * 2.0f;
401             Vector2 actual = Vector2.Lerp(a, b, t);
402             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
403         }
404 
405         // A test for Lerp (Vector2f, Vector2f, float)
406         // Lerp test with factor < 0
407         [Fact]
Vector2LerpTest4()408         public void Vector2LerpTest4()
409         {
410             Vector2 a = new Vector2(0.0f, 0.0f);
411             Vector2 b = new Vector2(3.18f, 4.25f);
412 
413             float t = -2.0f;
414             Vector2 expected = -(b * 2.0f);
415             Vector2 actual = Vector2.Lerp(a, b, t);
416             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
417         }
418 
419         // A test for Lerp (Vector2f, Vector2f, float)
420         // Lerp test with special float value
421         [Fact]
Vector2LerpTest5()422         public void Vector2LerpTest5()
423         {
424             Vector2 a = new Vector2(45.67f, 90.0f);
425             Vector2 b = new Vector2(float.PositiveInfinity, float.NegativeInfinity);
426 
427             float t = 0.408f;
428             Vector2 actual = Vector2.Lerp(a, b, t);
429             Assert.True(float.IsPositiveInfinity(actual.X), "Vector2f.Lerp did not return the expected value.");
430             Assert.True(float.IsNegativeInfinity(actual.Y), "Vector2f.Lerp did not return the expected value.");
431         }
432 
433         // A test for Lerp (Vector2f, Vector2f, float)
434         // Lerp test from the same point
435         [Fact]
Vector2LerpTest6()436         public void Vector2LerpTest6()
437         {
438             Vector2 a = new Vector2(1.0f, 2.0f);
439             Vector2 b = new Vector2(1.0f, 2.0f);
440 
441             float t = 0.5f;
442 
443             Vector2 expected = new Vector2(1.0f, 2.0f);
444             Vector2 actual = Vector2.Lerp(a, b, t);
445             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Lerp did not return the expected value.");
446         }
447 
448         // A test for Transform(Vector2f, Matrix4x4)
449         [Fact]
Vector2TransformTest()450         public void Vector2TransformTest()
451         {
452             Vector2 v = new Vector2(1.0f, 2.0f);
453             Matrix4x4 m =
454                 Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) *
455                 Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) *
456                 Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f));
457             m.M41 = 10.0f;
458             m.M42 = 20.0f;
459             m.M43 = 30.0f;
460 
461             Vector2 expected = new Vector2(10.316987f, 22.183012f);
462             Vector2 actual;
463 
464             actual = Vector2.Transform(v, m);
465             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
466         }
467 
468         // A test for Transform(Vector2f, Matrix3x2)
469         [Fact]
Vector2Transform3x2Test()470         public void Vector2Transform3x2Test()
471         {
472             Vector2 v = new Vector2(1.0f, 2.0f);
473             Matrix3x2 m = Matrix3x2.CreateRotation(MathHelper.ToRadians(30.0f));
474             m.M31 = 10.0f;
475             m.M32 = 20.0f;
476 
477             Vector2 expected = new Vector2(9.866025f, 22.23205f);
478             Vector2 actual;
479 
480             actual = Vector2.Transform(v, m);
481             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
482         }
483 
484         // A test for TransformNormal (Vector2f, Matrix4x4)
485         [Fact]
Vector2TransformNormalTest()486         public void Vector2TransformNormalTest()
487         {
488             Vector2 v = new Vector2(1.0f, 2.0f);
489             Matrix4x4 m =
490                 Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) *
491                 Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) *
492                 Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f));
493             m.M41 = 10.0f;
494             m.M42 = 20.0f;
495             m.M43 = 30.0f;
496 
497             Vector2 expected = new Vector2(0.3169873f, 2.18301272f);
498             Vector2 actual;
499 
500             actual = Vector2.TransformNormal(v, m);
501             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Tranform did not return the expected value.");
502         }
503 
504         // A test for TransformNormal (Vector2f, Matrix3x2)
505         [Fact]
Vector2TransformNormal3x2Test()506         public void Vector2TransformNormal3x2Test()
507         {
508             Vector2 v = new Vector2(1.0f, 2.0f);
509             Matrix3x2 m = Matrix3x2.CreateRotation(MathHelper.ToRadians(30.0f));
510             m.M31 = 10.0f;
511             m.M32 = 20.0f;
512 
513             Vector2 expected = new Vector2(-0.133974612f, 2.232051f);
514             Vector2 actual;
515 
516             actual = Vector2.TransformNormal(v, m);
517             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
518         }
519 
520         // A test for Transform (Vector2f, Quaternion)
521         [Fact]
Vector2TransformByQuaternionTest()522         public void Vector2TransformByQuaternionTest()
523         {
524             Vector2 v = new Vector2(1.0f, 2.0f);
525 
526             Matrix4x4 m =
527                 Matrix4x4.CreateRotationX(MathHelper.ToRadians(30.0f)) *
528                 Matrix4x4.CreateRotationY(MathHelper.ToRadians(30.0f)) *
529                 Matrix4x4.CreateRotationZ(MathHelper.ToRadians(30.0f));
530             Quaternion q = Quaternion.CreateFromRotationMatrix(m);
531 
532             Vector2 expected = Vector2.Transform(v, m);
533             Vector2 actual = Vector2.Transform(v, q);
534             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
535         }
536 
537         // A test for Transform (Vector2f, Quaternion)
538         // Transform Vector2f with zero quaternion
539         [Fact]
Vector2TransformByQuaternionTest1()540         public void Vector2TransformByQuaternionTest1()
541         {
542             Vector2 v = new Vector2(1.0f, 2.0f);
543             Quaternion q = new Quaternion();
544             Vector2 expected = v;
545 
546             Vector2 actual = Vector2.Transform(v, q);
547             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
548         }
549 
550         // A test for Transform (Vector2f, Quaternion)
551         // Transform Vector2f with identity quaternion
552         [Fact]
Vector2TransformByQuaternionTest2()553         public void Vector2TransformByQuaternionTest2()
554         {
555             Vector2 v = new Vector2(1.0f, 2.0f);
556             Quaternion q = Quaternion.Identity;
557             Vector2 expected = v;
558 
559             Vector2 actual = Vector2.Transform(v, q);
560             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Transform did not return the expected value.");
561         }
562 
563         // A test for Normalize (Vector2f)
564         [Fact]
Vector2NormalizeTest()565         public void Vector2NormalizeTest()
566         {
567             Vector2 a = new Vector2(2.0f, 3.0f);
568             Vector2 expected = new Vector2(0.554700196225229122018341733457f, 0.8320502943378436830275126001855f);
569             Vector2 actual;
570 
571             actual = Vector2.Normalize(a);
572             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Normalize did not return the expected value.");
573         }
574 
575         // A test for Normalize (Vector2f)
576         // Normalize zero length vector
577         [Fact]
Vector2NormalizeTest1()578         public void Vector2NormalizeTest1()
579         {
580             Vector2 a = new Vector2(); // no parameter, default to 0.0f
581             Vector2 actual = Vector2.Normalize(a);
582             Assert.True(float.IsNaN(actual.X) && float.IsNaN(actual.Y), "Vector2f.Normalize did not return the expected value.");
583         }
584 
585         // A test for Normalize (Vector2f)
586         // Normalize infinite length vector
587         [Fact]
Vector2NormalizeTest2()588         public void Vector2NormalizeTest2()
589         {
590             Vector2 a = new Vector2(float.MaxValue, float.MaxValue);
591             Vector2 actual = Vector2.Normalize(a);
592             Vector2 expected = new Vector2(0, 0);
593             Assert.Equal(expected, actual);
594         }
595 
596         // A test for operator - (Vector2f)
597         [Fact]
Vector2UnaryNegationTest()598         public void Vector2UnaryNegationTest()
599         {
600             Vector2 a = new Vector2(1.0f, 2.0f);
601 
602             Vector2 expected = new Vector2(-1.0f, -2.0f);
603             Vector2 actual;
604 
605             actual = -a;
606 
607             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator - did not return the expected value.");
608         }
609 
610 
611 
612         // A test for operator - (Vector2f)
613         // Negate test with special float value
614         [Fact]
Vector2UnaryNegationTest1()615         public void Vector2UnaryNegationTest1()
616         {
617             Vector2 a = new Vector2(float.PositiveInfinity, float.NegativeInfinity);
618 
619             Vector2 actual = -a;
620 
621             Assert.True(float.IsNegativeInfinity(actual.X), "Vector2f.operator - did not return the expected value.");
622             Assert.True(float.IsPositiveInfinity(actual.Y), "Vector2f.operator - did not return the expected value.");
623         }
624 
625         // A test for operator - (Vector2f)
626         // Negate test with special float value
627         [Fact]
Vector2UnaryNegationTest2()628         public void Vector2UnaryNegationTest2()
629         {
630             Vector2 a = new Vector2(float.NaN, 0.0f);
631             Vector2 actual = -a;
632 
633             Assert.True(float.IsNaN(actual.X), "Vector2f.operator - did not return the expected value.");
634             Assert.True(float.Equals(0.0f, actual.Y), "Vector2f.operator - did not return the expected value.");
635         }
636 
637         // A test for operator - (Vector2f, Vector2f)
638         [Fact]
Vector2SubtractionTest()639         public void Vector2SubtractionTest()
640         {
641             Vector2 a = new Vector2(1.0f, 3.0f);
642             Vector2 b = new Vector2(2.0f, 1.5f);
643 
644             Vector2 expected = new Vector2(-1.0f, 1.5f);
645             Vector2 actual;
646 
647             actual = a - b;
648 
649             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator - did not return the expected value.");
650         }
651 
652         // A test for operator * (Vector2f, float)
653         [Fact]
Vector2MultiplyOperatorTest()654         public void Vector2MultiplyOperatorTest()
655         {
656             Vector2 a = new Vector2(2.0f, 3.0f);
657             const float factor = 2.0f;
658 
659             Vector2 expected = new Vector2(4.0f, 6.0f);
660             Vector2 actual;
661 
662             actual = a * factor;
663             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator * did not return the expected value.");
664         }
665 
666         // A test for operator * (float, Vector2f)
667         [Fact]
Vector2MultiplyOperatorTest2()668         public void Vector2MultiplyOperatorTest2()
669         {
670             Vector2 a = new Vector2(2.0f, 3.0f);
671             const float factor = 2.0f;
672 
673             Vector2 expected = new Vector2(4.0f, 6.0f);
674             Vector2 actual;
675 
676             actual = factor * a;
677             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator * did not return the expected value.");
678         }
679 
680         // A test for operator * (Vector2f, Vector2f)
681         [Fact]
Vector2MultiplyOperatorTest3()682         public void Vector2MultiplyOperatorTest3()
683         {
684             Vector2 a = new Vector2(2.0f, 3.0f);
685             Vector2 b = new Vector2(4.0f, 5.0f);
686 
687             Vector2 expected = new Vector2(8.0f, 15.0f);
688             Vector2 actual;
689 
690             actual = a * b;
691 
692             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator * did not return the expected value.");
693         }
694 
695         // A test for operator / (Vector2f, float)
696         [Fact]
Vector2DivisionTest()697         public void Vector2DivisionTest()
698         {
699             Vector2 a = new Vector2(2.0f, 3.0f);
700 
701             float div = 2.0f;
702 
703             Vector2 expected = new Vector2(1.0f, 1.5f);
704             Vector2 actual;
705 
706             actual = a / div;
707 
708             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator / did not return the expected value.");
709         }
710 
711         // A test for operator / (Vector2f, Vector2f)
712         [Fact]
Vector2DivisionTest1()713         public void Vector2DivisionTest1()
714         {
715             Vector2 a = new Vector2(2.0f, 3.0f);
716             Vector2 b = new Vector2(4.0f, 5.0f);
717 
718             Vector2 expected = new Vector2(2.0f / 4.0f, 3.0f / 5.0f);
719             Vector2 actual;
720 
721             actual = a / b;
722 
723             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator / did not return the expected value.");
724         }
725 
726         // A test for operator / (Vector2f, float)
727         // Divide by zero
728         [Fact]
Vector2DivisionTest2()729         public void Vector2DivisionTest2()
730         {
731             Vector2 a = new Vector2(-2.0f, 3.0f);
732 
733             float div = 0.0f;
734 
735             Vector2 actual = a / div;
736 
737             Assert.True(float.IsNegativeInfinity(actual.X), "Vector2f.operator / did not return the expected value.");
738             Assert.True(float.IsPositiveInfinity(actual.Y), "Vector2f.operator / did not return the expected value.");
739         }
740 
741         // A test for operator / (Vector2f, Vector2f)
742         // Divide by zero
743         [Fact]
Vector2DivisionTest3()744         public void Vector2DivisionTest3()
745         {
746             Vector2 a = new Vector2(0.047f, -3.0f);
747             Vector2 b = new Vector2();
748 
749             Vector2 actual = a / b;
750 
751             Assert.True(float.IsInfinity(actual.X), "Vector2f.operator / did not return the expected value.");
752             Assert.True(float.IsInfinity(actual.Y), "Vector2f.operator / did not return the expected value.");
753         }
754 
755         // A test for operator + (Vector2f, Vector2f)
756         [Fact]
Vector2AdditionTest()757         public void Vector2AdditionTest()
758         {
759             Vector2 a = new Vector2(1.0f, 2.0f);
760             Vector2 b = new Vector2(3.0f, 4.0f);
761 
762             Vector2 expected = new Vector2(4.0f, 6.0f);
763             Vector2 actual;
764 
765             actual = a + b;
766 
767             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.operator + did not return the expected value.");
768         }
769 
770         // A test for Vector2f (float, float)
771         [Fact]
Vector2ConstructorTest()772         public void Vector2ConstructorTest()
773         {
774             float x = 1.0f;
775             float y = 2.0f;
776 
777             Vector2 target = new Vector2(x, y);
778             Assert.True(MathHelper.Equal(target.X, x) && MathHelper.Equal(target.Y, y), "Vector2f(x,y) constructor did not return the expected value.");
779         }
780 
781         // A test for Vector2f ()
782         // Constructor with no parameter
783         [Fact]
Vector2ConstructorTest2()784         public void Vector2ConstructorTest2()
785         {
786             Vector2 target = new Vector2();
787             Assert.Equal(target.X, 0.0f);
788             Assert.Equal(target.Y, 0.0f);
789         }
790 
791         // A test for Vector2f (float, float)
792         // Constructor with special floating values
793         [Fact]
Vector2ConstructorTest3()794         public void Vector2ConstructorTest3()
795         {
796             Vector2 target = new Vector2(float.NaN, float.MaxValue);
797             Assert.Equal(target.X, float.NaN);
798             Assert.Equal(target.Y, float.MaxValue);
799         }
800 
801         // A test for Vector2f (float)
802         [Fact]
Vector2ConstructorTest4()803         public void Vector2ConstructorTest4()
804         {
805             float value = 1.0f;
806             Vector2 target = new Vector2(value);
807 
808             Vector2 expected = new Vector2(value, value);
809             Assert.Equal(expected, target);
810 
811             value = 2.0f;
812             target = new Vector2(value);
813             expected = new Vector2(value, value);
814             Assert.Equal(expected, target);
815         }
816 
817         // A test for Add (Vector2f, Vector2f)
818         [Fact]
Vector2AddTest()819         public void Vector2AddTest()
820         {
821             Vector2 a = new Vector2(1.0f, 2.0f);
822             Vector2 b = new Vector2(5.0f, 6.0f);
823 
824             Vector2 expected = new Vector2(6.0f, 8.0f);
825             Vector2 actual;
826 
827             actual = Vector2.Add(a, b);
828             Assert.Equal(expected, actual);
829         }
830 
831         // A test for Divide (Vector2f, float)
832         [Fact]
Vector2DivideTest()833         public void Vector2DivideTest()
834         {
835             Vector2 a = new Vector2(1.0f, 2.0f);
836             float div = 2.0f;
837             Vector2 expected = new Vector2(0.5f, 1.0f);
838             Vector2 actual;
839             actual = Vector2.Divide(a, div);
840             Assert.Equal(expected, actual);
841         }
842 
843         // A test for Divide (Vector2f, Vector2f)
844         [Fact]
Vector2DivideTest1()845         public void Vector2DivideTest1()
846         {
847             Vector2 a = new Vector2(1.0f, 6.0f);
848             Vector2 b = new Vector2(5.0f, 2.0f);
849 
850             Vector2 expected = new Vector2(1.0f / 5.0f, 6.0f / 2.0f);
851             Vector2 actual;
852 
853             actual = Vector2.Divide(a, b);
854             Assert.Equal(expected, actual);
855         }
856 
857         // A test for Equals (object)
858         [Fact]
Vector2EqualsTest()859         public void Vector2EqualsTest()
860         {
861             Vector2 a = new Vector2(1.0f, 2.0f);
862             Vector2 b = new Vector2(1.0f, 2.0f);
863 
864             // case 1: compare between same values
865             object obj = b;
866 
867             bool expected = true;
868             bool actual = a.Equals(obj);
869             Assert.Equal(expected, actual);
870 
871             // case 2: compare between different values
872             b.X = 10.0f;
873             obj = b;
874             expected = false;
875             actual = a.Equals(obj);
876             Assert.Equal(expected, actual);
877 
878             // case 3: compare between different types.
879             obj = new Quaternion();
880             expected = false;
881             actual = a.Equals(obj);
882             Assert.Equal(expected, actual);
883 
884             // case 3: compare against null.
885             obj = null;
886             expected = false;
887             actual = a.Equals(obj);
888             Assert.Equal(expected, actual);
889         }
890 
891         // A test for Multiply (Vector2f, float)
892         [Fact]
Vector2MultiplyTest()893         public void Vector2MultiplyTest()
894         {
895             Vector2 a = new Vector2(1.0f, 2.0f);
896             const float factor = 2.0f;
897             Vector2 expected = new Vector2(2.0f, 4.0f);
898             Vector2 actual = Vector2.Multiply(a, factor);
899             Assert.Equal(expected, actual);
900         }
901 
902         // A test for Multiply (float, Vector2f)
903         [Fact]
Vector2MultiplyTest2()904         public void Vector2MultiplyTest2()
905         {
906             Vector2 a = new Vector2(1.0f, 2.0f);
907             const float factor = 2.0f;
908             Vector2 expected = new Vector2(2.0f, 4.0f);
909             Vector2 actual = Vector2.Multiply(factor, a);
910             Assert.Equal(expected, actual);
911         }
912 
913         // A test for Multiply (Vector2f, Vector2f)
914         [Fact]
Vector2MultiplyTest3()915         public void Vector2MultiplyTest3()
916         {
917             Vector2 a = new Vector2(1.0f, 2.0f);
918             Vector2 b = new Vector2(5.0f, 6.0f);
919 
920             Vector2 expected = new Vector2(5.0f, 12.0f);
921             Vector2 actual;
922 
923             actual = Vector2.Multiply(a, b);
924             Assert.Equal(expected, actual);
925         }
926 
927         // A test for Negate (Vector2f)
928         [Fact]
Vector2NegateTest()929         public void Vector2NegateTest()
930         {
931             Vector2 a = new Vector2(1.0f, 2.0f);
932 
933             Vector2 expected = new Vector2(-1.0f, -2.0f);
934             Vector2 actual;
935 
936             actual = Vector2.Negate(a);
937             Assert.Equal(expected, actual);
938         }
939 
940         // A test for operator != (Vector2f, Vector2f)
941         [Fact]
Vector2InequalityTest()942         public void Vector2InequalityTest()
943         {
944             Vector2 a = new Vector2(1.0f, 2.0f);
945             Vector2 b = new Vector2(1.0f, 2.0f);
946 
947             // case 1: compare between same values
948             bool expected = false;
949             bool actual = a != b;
950             Assert.Equal(expected, actual);
951 
952             // case 2: compare between different values
953             b.X = 10.0f;
954             expected = true;
955             actual = a != b;
956             Assert.Equal(expected, actual);
957         }
958 
959         // A test for operator == (Vector2f, Vector2f)
960         [Fact]
Vector2EqualityTest()961         public void Vector2EqualityTest()
962         {
963             Vector2 a = new Vector2(1.0f, 2.0f);
964             Vector2 b = new Vector2(1.0f, 2.0f);
965 
966             // case 1: compare between same values
967             bool expected = true;
968             bool actual = a == b;
969             Assert.Equal(expected, actual);
970 
971             // case 2: compare between different values
972             b.X = 10.0f;
973             expected = false;
974             actual = a == b;
975             Assert.Equal(expected, actual);
976         }
977 
978         // A test for Subtract (Vector2f, Vector2f)
979         [Fact]
Vector2SubtractTest()980         public void Vector2SubtractTest()
981         {
982             Vector2 a = new Vector2(1.0f, 6.0f);
983             Vector2 b = new Vector2(5.0f, 2.0f);
984 
985             Vector2 expected = new Vector2(-4.0f, 4.0f);
986             Vector2 actual;
987 
988             actual = Vector2.Subtract(a, b);
989             Assert.Equal(expected, actual);
990         }
991 
992         // A test for UnitX
993         [Fact]
Vector2UnitXTest()994         public void Vector2UnitXTest()
995         {
996             Vector2 val = new Vector2(1.0f, 0.0f);
997             Assert.Equal(val, Vector2.UnitX);
998         }
999 
1000         // A test for UnitY
1001         [Fact]
Vector2UnitYTest()1002         public void Vector2UnitYTest()
1003         {
1004             Vector2 val = new Vector2(0.0f, 1.0f);
1005             Assert.Equal(val, Vector2.UnitY);
1006         }
1007 
1008         // A test for One
1009         [Fact]
Vector2OneTest()1010         public void Vector2OneTest()
1011         {
1012             Vector2 val = new Vector2(1.0f, 1.0f);
1013             Assert.Equal(val, Vector2.One);
1014         }
1015 
1016         // A test for Zero
1017         [Fact]
Vector2ZeroTest()1018         public void Vector2ZeroTest()
1019         {
1020             Vector2 val = new Vector2(0.0f, 0.0f);
1021             Assert.Equal(val, Vector2.Zero);
1022         }
1023 
1024         // A test for Equals (Vector2f)
1025         [Fact]
Vector2EqualsTest1()1026         public void Vector2EqualsTest1()
1027         {
1028             Vector2 a = new Vector2(1.0f, 2.0f);
1029             Vector2 b = new Vector2(1.0f, 2.0f);
1030 
1031             // case 1: compare between same values
1032             bool expected = true;
1033             bool actual = a.Equals(b);
1034             Assert.Equal(expected, actual);
1035 
1036             // case 2: compare between different values
1037             b.X = 10.0f;
1038             expected = false;
1039             actual = a.Equals(b);
1040             Assert.Equal(expected, actual);
1041         }
1042 
1043         // A test for Vector2f comparison involving NaN values
1044         [Fact]
Vector2EqualsNanTest()1045         public void Vector2EqualsNanTest()
1046         {
1047             Vector2 a = new Vector2(float.NaN, 0);
1048             Vector2 b = new Vector2(0, float.NaN);
1049 
1050             Assert.False(a == Vector2.Zero);
1051             Assert.False(b == Vector2.Zero);
1052 
1053             Assert.True(a != Vector2.Zero);
1054             Assert.True(b != Vector2.Zero);
1055 
1056             Assert.False(a.Equals(Vector2.Zero));
1057             Assert.False(b.Equals(Vector2.Zero));
1058 
1059             // Counterintuitive result - IEEE rules for NaN comparison are weird!
1060             Assert.False(a.Equals(a));
1061             Assert.False(b.Equals(b));
1062         }
1063 
1064         // A test for Reflect (Vector2f, Vector2f)
1065         [Fact]
Vector2ReflectTest()1066         public void Vector2ReflectTest()
1067         {
1068             Vector2 a = Vector2.Normalize(new Vector2(1.0f, 1.0f));
1069 
1070             // Reflect on XZ plane.
1071             Vector2 n = new Vector2(0.0f, 1.0f);
1072             Vector2 expected = new Vector2(a.X, -a.Y);
1073             Vector2 actual = Vector2.Reflect(a, n);
1074             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Reflect did not return the expected value.");
1075 
1076             // Reflect on XY plane.
1077             n = new Vector2(0.0f, 0.0f);
1078             expected = new Vector2(a.X, a.Y);
1079             actual = Vector2.Reflect(a, n);
1080             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Reflect did not return the expected value.");
1081 
1082             // Reflect on YZ plane.
1083             n = new Vector2(1.0f, 0.0f);
1084             expected = new Vector2(-a.X, a.Y);
1085             actual = Vector2.Reflect(a, n);
1086             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Reflect did not return the expected value.");
1087         }
1088 
1089         // A test for Reflect (Vector2f, Vector2f)
1090         // Reflection when normal and source are the same
1091         [Fact]
Vector2ReflectTest1()1092         public void Vector2ReflectTest1()
1093         {
1094             Vector2 n = new Vector2(0.45f, 1.28f);
1095             n = Vector2.Normalize(n);
1096             Vector2 a = n;
1097 
1098             Vector2 expected = -n;
1099             Vector2 actual = Vector2.Reflect(a, n);
1100             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Reflect did not return the expected value.");
1101         }
1102 
1103         // A test for Reflect (Vector2f, Vector2f)
1104         // Reflection when normal and source are negation
1105         [Fact]
Vector2ReflectTest2()1106         public void Vector2ReflectTest2()
1107         {
1108             Vector2 n = new Vector2(0.45f, 1.28f);
1109             n = Vector2.Normalize(n);
1110             Vector2 a = -n;
1111 
1112             Vector2 expected = n;
1113             Vector2 actual = Vector2.Reflect(a, n);
1114             Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Reflect did not return the expected value.");
1115         }
1116 
1117         [Fact]
Vector2AbsTest()1118         public void Vector2AbsTest()
1119         {
1120             Vector2 v1 = new Vector2(-2.5f, 2.0f);
1121             Vector2 v3 = Vector2.Abs(new Vector2(0.0f, Single.NegativeInfinity));
1122             Vector2 v = Vector2.Abs(v1);
1123             Assert.Equal(2.5f, v.X);
1124             Assert.Equal(2.0f, v.Y);
1125             Assert.Equal(0.0f, v3.X);
1126             Assert.Equal(Single.PositiveInfinity, v3.Y);
1127         }
1128 
1129         [Fact]
Vector2SqrtTest()1130         public void Vector2SqrtTest()
1131         {
1132             Vector2 v1 = new Vector2(-2.5f, 2.0f);
1133             Vector2 v2 = new Vector2(5.5f, 4.5f);
1134             Assert.Equal(2, (int)Vector2.SquareRoot(v2).X);
1135             Assert.Equal(2, (int)Vector2.SquareRoot(v2).Y);
1136             Assert.Equal(Single.NaN, Vector2.SquareRoot(v1).X);
1137         }
1138 
1139         // A test to make sure these types are blittable directly into GPU buffer memory layouts
1140         [Fact]
1141 #if MONO
1142         [ActiveIssue("https://bugzilla.xamarin.com/show_bug.cgi?id=57336")]
1143 #endif
Vector2SizeofTest()1144         public unsafe void Vector2SizeofTest()
1145         {
1146             Assert.Equal(8, sizeof(Vector2));
1147             Assert.Equal(16, sizeof(Vector2_2x));
1148             Assert.Equal(12, sizeof(Vector2PlusFloat));
1149             Assert.Equal(24, sizeof(Vector2PlusFloat_2x));
1150         }
1151 
1152         [StructLayout(LayoutKind.Sequential)]
1153         struct Vector2_2x
1154         {
1155             private Vector2 _a;
1156             private Vector2 _b;
1157         }
1158 
1159         [StructLayout(LayoutKind.Sequential)]
1160         struct Vector2PlusFloat
1161         {
1162             private Vector2 _v;
1163             private float _f;
1164         }
1165 
1166         [StructLayout(LayoutKind.Sequential)]
1167         struct Vector2PlusFloat_2x
1168         {
1169             private Vector2PlusFloat _a;
1170             private Vector2PlusFloat _b;
1171         }
1172 
1173         [Fact]
SetFieldsTest()1174         public void SetFieldsTest()
1175         {
1176             Vector2 v3 = new Vector2(4f, 5f);
1177             v3.X = 1.0f;
1178             v3.Y = 2.0f;
1179             Assert.Equal(1.0f, v3.X);
1180             Assert.Equal(2.0f, v3.Y);
1181             Vector2 v4 = v3;
1182             v4.Y = 0.5f;
1183             Assert.Equal(1.0f, v4.X);
1184             Assert.Equal(0.5f, v4.Y);
1185             Assert.Equal(2.0f, v3.Y);
1186         }
1187 
1188         [Fact]
EmbeddedVectorSetFields()1189         public void EmbeddedVectorSetFields()
1190         {
1191             EmbeddedVectorObject evo = new EmbeddedVectorObject();
1192             evo.FieldVector.X = 5.0f;
1193             evo.FieldVector.Y = 5.0f;
1194             Assert.Equal(5.0f, evo.FieldVector.X);
1195             Assert.Equal(5.0f, evo.FieldVector.Y);
1196         }
1197 
1198         private class EmbeddedVectorObject
1199         {
1200             public Vector2 FieldVector;
1201         }
1202     }
1203 }
1204