Jypeli 10
The simple game programming library
Vector.cs
Siirry tämän tiedoston dokumentaatioon.
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using AdvanceMath;
32using System.Globalization;
33using System.Collections.Generic;
34
35using Matrix = Microsoft.Xna.Framework.Matrix;
36
37namespace Jypeli
38{
39 // NOTES:
40 //
41 // TJ: In addition to the types Vector2 from XNA and Vector2D from AdvanceMath, we
42 // have a vector type of our own!
43 //
44 // PROS:
45 // * No need to have "using AdvanceMath" in games, keeps the interface clean and simple.
46 // * Has less methods and properties, again keeping the interface clean and simple.
47 // * Less typing in the name :P
48 //
49 // CONS:
50 // * Does it add overhead in execution? I don't think so, if the compiler is smart at all.
51 // Since the vectors are struct types, their handling should be done entirely in the stack.
52
53 // MR, 2021:
54 // TODO: AdvancedMath paketista voisi hiljalleen alkaa luopumaan.
55 // On hieman hämmentävää kun löytyy neljää eri vektoria (Jypeli, AdvancedMath, MonoGame sekä System.Numerics).
56 // Nyt kuitenkin onnistuu kaikkien noiden konversiot Jypelin kanssa.
57 // MonoGame on (ehkä joskus) vaihtamassa System.Numericsin vektoreihin ja matriiseihin.
58
59 // Matriisit voisi myös tuoda suoraan Jypelin puolelle, niille löytyy kuitenkin käyttöä sieltä sun täältä.
60
61
65 [Save]
66 public struct Vector
67 {
71 public static readonly Vector Zero = new Vector( 0, 0 );
72
76 public static readonly Vector One = new Vector( 1, 1 );
77
81 public static readonly Vector UnitX = new Vector( 1.0, 0.0 );
82
86 public static readonly Vector UnitY = new Vector( 0.0, 1.0 );
87
91 public static readonly Vector Diagonal = Vector.One;
92
97 {
98 get { return new Vector( -Y, X ); }
99 }
100
105 {
106 get { return new Vector( Y, -X ); }
107 }
108
114 private static Vector FromLengthAndAngle( double length, double angle )
115 {
116 Vector result;
117 result.X = length * Math.Cos( angle );
118 result.Y = length * Math.Sin( angle );
119 return result;
120 }
121
125 public static Vector FromLengthAndAngle( double length, Angle angle )
126 {
127 return FromLengthAndAngle( length, angle.Radians );
128 }
129
133 public static Vector FromAngle( Angle angle )
134 {
135 return FromLengthAndAngle( 1, angle.Radians );
136 }
137
141 public static double Distance( Vector p1, Vector p2 )
142 {
143 double x, y;
144 x = p1.X - p2.X;
145 y = p1.Y - p2.Y;
146 return Math.Sqrt( (float)(x * x + y * y) );
147 }
148
155 public static double DotProduct( Vector left, Vector right )
156 {
157 return left.Y * right.Y + left.X * right.X;
158 }
159
168 public static double CrossProduct( Vector left, Vector right )
169 {
170 return left.Magnitude * right.Magnitude * ( right.Angle - left.Angle ).Sin;
171 }
172
179 public static Vector ComponentProduct( Vector a, Vector b )
180 {
181 return new Vector( a.X * b.X, a.Y * b.Y );
182 }
183
189 public double Distance(Vector vector)
190 {
191 return Distance(this, vector);
192 }
193
200 public double ScalarProjection(Vector vector)
201 {
202 return (Vector.DotProduct(this, vector) / vector.MagnitudeSquared);
203 }
204
208 public Vector Project( Vector to )
209 {
210 return ScalarProjection( to ) * to;
211 }
212
218 {
219 return this / this.Magnitude;
220 }
221
227 public Vector Transform( Matrix matrix )
228 {
229 return new Vector
230 (
231 ( X * matrix.M11 ) + ( Y * matrix.M21 ) + matrix.M41,
232 ( X * matrix.M12 ) + ( Y * matrix.M22 ) + matrix.M42
233 );
234 }
235
241 {
242 return new Vector( Y, X );
243 }
244
250 public static Vector Min( params Vector[] vectors )
251 {
252 int minIndex = 0;
253 double minMagnitude = vectors[0].Magnitude;
254
255 for ( int i = 1; i < vectors.Length; i++ )
256 {
257 double m = vectors[i].Magnitude;
258 if ( m < minMagnitude )
259 {
260 minIndex = i;
261 minMagnitude = m;
262 }
263 }
264
265 return vectors[minIndex];
266 }
267
273 public static Vector Max( params Vector[] vectors )
274 {
275 int maxIndex = 0;
276 double maxMagnitude = vectors[0].Magnitude;
277
278 for ( int i = 1; i < vectors.Length; i++ )
279 {
280 double m = vectors[i].Magnitude;
281 if ( m > maxMagnitude )
282 {
283 maxIndex = i;
284 maxMagnitude = m;
285 }
286 }
287
288 return vectors[maxIndex];
289 }
290
296 public static Vector Average( IEnumerable<Vector> vectors )
297 {
298 double sumX = 0;
299 double sumY = 0;
300 int count = 0;
301
302 foreach ( var v in vectors )
303 {
304 sumX += v.X;
305 sumY += v.Y;
306 count++;
307 }
308
309 return count > 0 ? new Vector( sumX, sumY ) / count : Vector.Zero;
310 }
311
317 public static Vector Average( params Vector[] vectors )
318 {
319 double sumX = 0;
320 double sumY = 0;
321
322 foreach ( var v in vectors )
323 {
324 sumX += v.X;
325 sumY += v.Y;
326 }
327
328 return vectors.Length > 0 ? new Vector( sumX, sumY ) / vectors.Length : Vector.Zero;
329 }
330
334 [Save] public double X;
335
339 [Save] public double Y;
340
344 public double Magnitude
345 {
346 get { return Math.Sqrt( MagnitudeSquared ); }
347 }
348
352 public double MagnitudeSquared
353 {
354 get { return X * X + Y * Y; }
355 }
356
362 public Vector( double X, double Y )
363 {
364 this.X = X;
365 this.Y = Y;
366 }
367
372 {
373 get
374 {
375 double a = Math.Atan2( Y, X );
376 if ( a < 0 )
377 a += 2 * Math.PI;
378 return Angle.FromRadians( a );
379 }
380 }
381
386 public override string ToString()
387 {
388 return ToString( NumberFormatInfo.InvariantInfo );
389 }
390
397 public string ToString( IFormatProvider formatProvider )
398 {
399 string x = X.ToString( formatProvider );
400 string y = Y.ToString( formatProvider );
401 return string.Format( "({0},{1})", x, y );
402 }
403
409 public static Vector Parse( string vectorStr )
410 {
411 return Parse( vectorStr, NumberFormatInfo.InvariantInfo );
412 }
413
421 public static Vector Parse( string vectorStr, IFormatProvider formatProvider )
422 {
423 string[] splitStr = vectorStr.Split( '(', ',', ')' );
424
425 if ( splitStr.Length != 4 )
426 throw new FormatException( "Not a vector string: " + vectorStr );
427
428 double x = double.Parse( splitStr[1], formatProvider );
429 double y = double.Parse( splitStr[2], formatProvider );
430
431 return new Vector( x, y );
432 }
433
438 public override int GetHashCode()
439 {
440 return HashCode.Combine(X.GetHashCode(), Y.GetHashCode());
441 }
442
449 public override bool Equals(Object obj)
450 {
451 if (obj is not Vector) return false;
452
453 Vector v = (Vector)obj;
454
455 double x = v.X;
456 double y = v.Y;
457
458 return (Math.Abs(X - x) < double.Epsilon) && (Math.Abs(Y - y) < double.Epsilon);
459 }
460
461 #region operators
462
469 public static Vector operator +(Vector left, Vector right)
470 {
471 Vector result;
472 result.X = left.X + right.X;
473 result.Y = left.Y + right.Y;
474 return result;
475 }
476
483 public static Vector operator -(Vector left, Vector right)
484 {
485 Vector result;
486 result.X = left.X - right.X;
487 result.Y = left.Y - right.Y;
488 return result;
489 }
490
497 public static Vector operator *(Vector source, double scalar)
498 {
499 Vector result;
500 result.X = source.X * scalar;
501 result.Y = source.Y * scalar;
502 return result;
503 }
504
511 public static Vector operator *(double scalar, Vector source)
512 {
513 return source * scalar;
514 }
515
522 public static Vector operator /(Vector source, double scalar)
523 {
524 // TJ: Let's not implement this using operator* in order to
525 // avoid rounding errors.
526 Vector result;
527 result.X = source.X / scalar;
528 result.Y = source.Y / scalar;
529 return result;
530 }
531
537 public static Vector operator -(Vector source)
538 {
539 Vector result;
540 result.X = -source.X;
541 result.Y = -source.Y;
542 return result;
543 }
544
551 public static bool operator ==( Vector left, Vector right )
552 {
553 return ( Math.Abs( left.X - right.X ) < double.Epsilon ) && ( Math.Abs( left.Y - right.Y ) < double.Epsilon );
554 }
555
562 public static bool operator !=( Vector left, Vector right )
563 {
564 return !( left == right );
565 }
566
567 #region AdvMath conversions
568
573 public static implicit operator Vector(Vector2D v)
574 {
575 return new Vector(v.X, v.Y);
576 }
577
582 public static implicit operator Vector2D(Vector v)
583 {
584 return new Vector2D(v.X, v.Y);
585 }
586
587 #endregion
588 #region MonoGame conversions
589
594 public static implicit operator Vector(Microsoft.Xna.Framework.Vector2 v)
595 {
596 return new Vector(v.X, v.Y);
597 }
598
603 public static implicit operator Microsoft.Xna.Framework.Vector2(Vector v)
604 {
605 return new Microsoft.Xna.Framework.Vector2((float)v.X, (float)v.Y);
606 }
607
612 public static implicit operator Vector(Microsoft.Xna.Framework.Vector3 v)
613 {
614 return new Vector(v.X, v.Y);
615 }
616
621 public static implicit operator Microsoft.Xna.Framework.Vector3(Vector v)
622 {
623 return new Microsoft.Xna.Framework.Vector3((float)v.X, (float)v.Y, 0);
624 }
625
630 public static implicit operator Vector(Microsoft.Xna.Framework.Vector4 v)
631 {
632 return new Vector(v.X, v.Y);
633 }
634
639 public static implicit operator Microsoft.Xna.Framework.Vector4(Vector v)
640 {
641 return new Microsoft.Xna.Framework.Vector4((float)v.X, (float)v.Y, 0, 0);
642 }
643
644 #endregion
645 #region System.Numerics conversions
646
651 public static implicit operator Vector(System.Numerics.Vector2 v)
652 {
653 return new Vector(v.X, v.Y);
654 }
655
660 public static implicit operator System.Numerics.Vector2(Vector v)
661 {
662 return new System.Numerics.Vector2((float)v.X, (float)v.Y);
663 }
664
669 public static implicit operator Vector(System.Numerics.Vector3 v)
670 {
671 return new Vector(v.X, v.Y);
672 }
673
678 public static implicit operator System.Numerics.Vector3(Vector v)
679 {
680 return new System.Numerics.Vector3((float)v.X, (float)v.Y, 0);
681 }
682
687 public static implicit operator Vector(System.Numerics.Vector4 v)
688 {
689 return new Vector(v.X, v.Y);
690 }
691
696 public static implicit operator System.Numerics.Vector4(Vector v)
697 {
698 return new System.Numerics.Vector4((float)v.X, (float)v.Y, 0, 0);
699 }
700 #endregion
701 #endregion
702 }
703}
Microsoft.Xna.Framework.Matrix Matrix
Definition: Vector.cs:35
Microsoft.Xna.Framework.Matrix Matrix
Definition: Mouse.cs:36
This is the Vector Class.
Definition: Vector2D.cs:50
Scalar X
This is the X value. (Usually represents a horizontal position or direction.)
Definition: Vector2D.cs:796
Scalar Y
This is the Y value. (Usually represents a vertical position or direction.)
Definition: Vector2D.cs:805
Suuntakulma (rajoitettu -180 ja 180 asteen välille) asteina ja radiaaneina. Tietoja kulmasta: http://...
Definition: Angle.cs:40
static Angle FromRadians(double radian)
Luo kulman annettujen radiaanien mukaan.
Definition: Angle.cs:315
double Radians
Palauttaa tai asettaa kulman radiaaneina.
Definition: Angle.cs:85
2D-vektori.
Definition: Vector.cs:67
static Vector operator/(Vector source, double scalar)
Jakaa vektorin skalaarilla
Definition: Vector.cs:522
Vector LeftNormal
Vasen normaali.
Definition: Vector.cs:97
static Vector Max(params Vector[] vectors)
Palauttaa pisimmän vektorin.
Definition: Vector.cs:273
double Y
Vektorin Y-komponentti
Definition: Vector.cs:339
Vector Transform(Matrix matrix)
Kertoo vektorin matriisilla.
Definition: Vector.cs:227
Vector Normalize()
Palauttaa uuden vektorin, jonka suunta pysyy samana, mutta pituudeksi tulee 1.0.
Definition: Vector.cs:217
Vector RightNormal
Oikea normaali.
Definition: Vector.cs:105
static Vector FromAngle(Angle angle)
Luo vektorin kulman perusteella yksikköpituudella.
Definition: Vector.cs:133
static Vector Parse(string vectorStr)
Muodostaa (x,y) muodossa olevasta merkkijonsta vektorin
Definition: Vector.cs:409
static bool operator!=(Vector left, Vector right)
Ovatko vektorit eri
Definition: Vector.cs:562
override string ToString()
Vektori merkkijonona muodossa (x,y)
Definition: Vector.cs:386
Vector Project(Vector to)
Laskee ja palauttaa tämän pisteen etäisyyden toiseen pisteeseen.
Definition: Vector.cs:208
override int GetHashCode()
Vektorin hajautuskoodi
Definition: Vector.cs:438
static double Distance(Vector p1, Vector p2)
Etäisyys kahden pisteen välillä.
Definition: Vector.cs:141
static readonly Vector One
Yksikkövektori.
Definition: Vector.cs:76
static readonly Vector Zero
Nollavektori.
Definition: Vector.cs:71
static Vector FromLengthAndAngle(double length, Angle angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:125
double X
Vektorin X-komponentti.
Definition: Vector.cs:334
Angle Angle
Kulma radiaaneina.
Definition: Vector.cs:372
static Vector Parse(string vectorStr, IFormatProvider formatProvider)
Muodostaa (x,y) muodossa olevasta merkkijonsta vektorin, jossa x ja y on muotoiltu annetun formaatin ...
Definition: Vector.cs:421
double MagnitudeSquared
Vektorin pituuden neliö.
Definition: Vector.cs:353
static Vector Min(params Vector[] vectors)
Palauttaa lyhimmän vektorin.
Definition: Vector.cs:250
static Vector Average(IEnumerable< Vector > vectors)
Palauttaa kahden tai useamman vektorin keskiarvon.
Definition: Vector.cs:296
static Vector ComponentProduct(Vector a, Vector b)
Kertoo kaksi vektoria komponenteittain.
Definition: Vector.cs:179
static readonly Vector Diagonal
Diagonaalivektori (1,1)
Definition: Vector.cs:91
static Vector operator*(Vector source, double scalar)
Kertoo vektorin skalaarilla
Definition: Vector.cs:497
static Vector Average(params Vector[] vectors)
Palauttaa kahden tai useamman vektorin keskiarvon.
Definition: Vector.cs:317
override bool Equals(Object obj)
Onko annettu vektori yhtäsuuri tämän kanssa. Tosi, jos vektorien komponentit ovat double....
Definition: Vector.cs:449
static bool operator==(Vector left, Vector right)
Ovatko vektorit samat
Definition: Vector.cs:551
static Vector operator+(Vector left, Vector right)
Summaa vektorit yhteen
Definition: Vector.cs:469
static readonly Vector UnitY
Pystysuuntainen yksikkövektori (pituus 1, suunta ylös).
Definition: Vector.cs:86
Vector(double X, double Y)
Luo uuden vektorin komponenteista.
Definition: Vector.cs:362
static readonly Vector UnitX
Vaakasuuntainen yksikkövektori (pituus 1, suunta oikealle).
Definition: Vector.cs:81
double ScalarProjection(Vector vector)
Skalaariprojektio annettuun vektoriin https://en.wikipedia.org/wiki/Scalar_projection
Definition: Vector.cs:200
static double DotProduct(Vector left, Vector right)
Pistetulo.
Definition: Vector.cs:155
double Magnitude
Vektorin pituus.
Definition: Vector.cs:345
static double CrossProduct(Vector left, Vector right)
Ristitulo. Palauttaa kohtisuoraan vektoreita vastaan olevan uuden vektorin pituuden....
Definition: Vector.cs:168
Vector Transpose()
Palauttaa uuden vektorin, jossa x ja y on vaihdettu keskenään.
Definition: Vector.cs:240
static Vector operator-(Vector left, Vector right)
Vähentää vektorit toisistaan
Definition: Vector.cs:483
string ToString(IFormatProvider formatProvider)
Vektori merkkijonona muodossa (x,y), jossa x ja y on muotoiltu annetun formaatin mukaisesti
Definition: Vector.cs:397
double Distance(Vector vector)
Etäisyys kahden pisteen välillä
Definition: Vector.cs:189
static Vector FromLengthAndAngle(double length, double angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:114