Jypeli  9
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 
30 using System;
31 using AdvanceMath;
32 using System.Globalization;
33 using System.Collections.Generic;
34 
35 using Matrix = Microsoft.Xna.Framework.Matrix;
36 
37 namespace 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 
57  [Save]
58  public struct Vector
59  {
63  public static readonly Vector Zero = new Vector( 0, 0 );
64 
68  public static readonly Vector One = new Vector( 1, 1 );
69 
73  public static readonly Vector UnitX = new Vector( 1.0, 0.0 );
74 
78  public static readonly Vector UnitY = new Vector( 0.0, 1.0 );
79 
83  public static readonly Vector Diagonal = Vector.One;
84 
89  {
90  get { return new Vector( -Y, X ); }
91  }
92 
97  {
98  get { return new Vector( Y, -X ); }
99  }
100 
106  private static Vector FromLengthAndAngle( double length, double angle )
107  {
108  Vector result;
109  result.X = length * Math.Cos( angle );
110  result.Y = length * Math.Sin( angle );
111  return result;
112  }
113 
117  public static Vector FromLengthAndAngle( double length, Angle angle )
118  {
119  return FromLengthAndAngle( length, angle.Radians );
120  }
121 
125  public static Vector FromAngle( Angle angle )
126  {
127  return FromLengthAndAngle( 1, angle.Radians );
128  }
129 
133  public static double Distance( Vector p1, Vector p2 )
134  {
135  double x, y;
136  x = p1.X - p2.X;
137  y = p1.Y - p2.Y;
138  return MathHelper.Sqrt( (float)(x * x + y * y) );
139  }
140 
147  public static double DotProduct( Vector left, Vector right )
148  {
149  return left.Y * right.Y + left.X * right.X;
150  }
151 
160  public static double CrossProduct( Vector left, Vector right )
161  {
162  return left.Magnitude * right.Magnitude * ( right.Angle - left.Angle ).Sin;
163  }
164 
171  public static Vector ComponentProduct( Vector a, Vector b )
172  {
173  return new Vector( a.X * b.X, a.Y * b.Y );
174  }
175 
176  public double Distance(Vector2D vector)
177  {
178  return Distance(this, vector);
179  }
180 
181  public double ScalarProjection( Vector unitVector )
182  {
183  return ( Vector.DotProduct( this, unitVector ) / unitVector.MagnitudeSquared );
184  }
185 
189  public Vector Project( Vector to )
190  {
191  return ScalarProjection( to ) * to;
192  }
193 
198  public Vector Normalize()
199  {
200  return this / this.Magnitude;
201  }
202 
208  public Vector Transform( Matrix matrix )
209  {
210  return new Vector
211  (
212  ( X * matrix.M11 ) + ( Y * matrix.M21 ) + matrix.M41,
213  ( X * matrix.M12 ) + ( Y * matrix.M22 ) + matrix.M42
214  );
215  }
216 
221  public Vector Transpose()
222  {
223  return new Vector( Y, X );
224  }
225 
231  public static Vector Min( params Vector[] vectors )
232  {
233  int minIndex = 0;
234  double minMagnitude = vectors[0].Magnitude;
235 
236  for ( int i = 1; i < vectors.Length; i++ )
237  {
238  double m = vectors[i].Magnitude;
239  if ( m < minMagnitude )
240  {
241  minIndex = i;
242  minMagnitude = m;
243  }
244  }
245 
246  return vectors[minIndex];
247  }
248 
254  public static Vector Max( params Vector[] vectors )
255  {
256  int maxIndex = 0;
257  double maxMagnitude = vectors[0].Magnitude;
258 
259  for ( int i = 1; i < vectors.Length; i++ )
260  {
261  double m = vectors[i].Magnitude;
262  if ( m > maxMagnitude )
263  {
264  maxIndex = i;
265  maxMagnitude = m;
266  }
267  }
268 
269  return vectors[maxIndex];
270  }
271 
277  public static Vector Average( IEnumerable<Vector> vectors )
278  {
279  double sumX = 0;
280  double sumY = 0;
281  int count = 0;
282 
283  foreach ( var v in vectors )
284  {
285  sumX += v.X;
286  sumY += v.Y;
287  count++;
288  }
289 
290  return count > 0 ? new Vector( sumX, sumY ) / count : Vector.Zero;
291  }
292 
298  public static Vector Average( params Vector[] vectors )
299  {
300  double sumX = 0;
301  double sumY = 0;
302 
303  foreach ( var v in vectors )
304  {
305  sumX += v.X;
306  sumY += v.Y;
307  }
308 
309  return vectors.Length > 0 ? new Vector( sumX, sumY ) / vectors.Length : Vector.Zero;
310  }
311 
312  [Save] public double X;
313  [Save] public double Y;
314 
318  public double Magnitude
319  {
320  get { return Math.Sqrt( MagnitudeSquared ); }
321  }
322 
326  public double MagnitudeSquared
327  {
328  get { return X * X + Y * Y; }
329  }
330 
336  public Vector( double X, double Y )
337  {
338  this.X = X;
339  this.Y = Y;
340  }
341 
345  public Angle Angle
346  {
347  get
348  {
349  double a = Math.Atan2( Y, X );
350  if ( a < 0 )
351  a += 2 * Math.PI;
352  return Angle.FromRadians( a );
353  }
354  }
355 
360  public override string ToString()
361  {
362  return ToString( NumberFormatInfo.InvariantInfo );
363  }
364 
365  public string ToString( IFormatProvider formatProvider )
366  {
367  string x = X.ToString( formatProvider );
368  string y = Y.ToString( formatProvider );
369  return string.Format( "({0},{1})", x, y );
370  }
371 
372  public static Vector Parse( string vectorStr )
373  {
374  return Parse( vectorStr, NumberFormatInfo.InvariantInfo );
375  }
376 
377  public static Vector Parse( string vectorStr, IFormatProvider formatProvider )
378  {
379  string[] splitStr = vectorStr.Split( '(', ',', ')' );
380 
381  if ( splitStr.Length != 4 )
382  throw new FormatException( "Not a vector string: " + vectorStr );
383 
384  double x = double.Parse( splitStr[1], formatProvider );
385  double y = double.Parse( splitStr[2], formatProvider );
386 
387  return new Vector( x, y );
388  }
389 
390  public static Vector operator +( Vector left, Vector right )
391  {
392  Vector result;
393  result.X = left.X + right.X;
394  result.Y = left.Y + right.Y;
395  return result;
396  }
397 
398  public static Vector operator -( Vector left, Vector right )
399  {
400  Vector result;
401  result.X = left.X - right.X;
402  result.Y = left.Y - right.Y;
403  return result;
404  }
405 
406  public static Vector operator *( Vector source, double scalar )
407  {
408  Vector result;
409  result.X = source.X * scalar;
410  result.Y = source.Y * scalar;
411  return result;
412  }
413 
414  public static Vector operator *( double scalar, Vector source )
415  {
416  return source * scalar;
417  }
418 
419  public static Vector operator /( Vector source, double scalar )
420  {
421  // TJ: Let's not implement this using operator* in order to
422  // avoid rounding errors.
423  Vector result;
424  result.X = source.X / scalar;
425  result.Y = source.Y / scalar;
426  return result;
427  }
428 
429  public static Vector operator -( Vector source )
430  {
431  Vector result;
432  result.X = -source.X;
433  result.Y = -source.Y;
434  return result;
435  }
436 
437  public override int GetHashCode()
438  {
439  return ObjectHelper.GetHashCode( X.GetHashCode(), Y.GetHashCode() );
440  }
441 
442  public override bool Equals( object obj )
443  {
444  double x, y;
445 
446  if ( obj is Vector )
447  {
448  x = ( (Vector)obj ).X;
449  y = ( (Vector)obj ).Y;
450  }
451  else if ( obj is Vector2D )
452  {
453  x = ( (Vector2D)obj ).X;
454  y = ( (Vector2D)obj ).Y;
455  }
456  else if ( obj is Vector3D )
457  {
458  x = ( (Vector3D)obj ).X;
459  y = ( (Vector3D)obj ).Y;
460  }
461  else if ( obj is Vector4D )
462  {
463  x = ( (Vector4D)obj ).X;
464  y = ( (Vector4D)obj ).Y;
465  }
466  else
467  return false;
468 
469 #if WINDOWS_PHONE
470  // TK: Double.Epsilon is too small for the phone to recognize
471  return ( Math.Abs( this.X - x ) < float.Epsilon ) && ( Math.Abs( this.Y - y ) < float.Epsilon );
472 #else
473  return ( Math.Abs( this.X - x ) < double.Epsilon ) && ( Math.Abs( this.Y - y ) < double.Epsilon );
474 #endif
475  }
476 
477  public static bool operator ==( Vector left, Vector right )
478  {
479 #if WINDOWS_PHONE || ANDROID
480  // TK: Double.Epsilon is too small for the phone to recognize
481  return ( Math.Abs( left.X - right.X ) < float.Epsilon ) && ( Math.Abs( left.Y - right.Y ) < float.Epsilon );
482 #else
483  return ( Math.Abs( left.X - right.X ) < double.Epsilon ) && ( Math.Abs( left.Y - right.Y ) < double.Epsilon );
484 #endif
485  }
486 
487  public static bool operator !=( Vector left, Vector right )
488  {
489  return !( left == right );
490  }
491 
492  public static implicit operator Vector( Vector2D v )
493  {
494  return new Vector( v.X, v.Y );
495  }
496 
497  public static implicit operator Vector2D( Vector v )
498  {
499  return new Vector2D( v.X, v.Y );
500  }
501 
502  public static implicit operator Vector( Microsoft.Xna.Framework.Vector2 v )
503  {
504  return new Vector( v.X, v.Y );
505  }
506 
507  public static implicit operator Microsoft.Xna.Framework.Vector2( Vector v )
508  {
509  return new Microsoft.Xna.Framework.Vector2( (float)v.X, (float)v.Y );
510  }
511 
512  public static implicit operator Vector( Microsoft.Xna.Framework.Vector3 v )
513  {
514  return new Vector( v.X, v.Y );
515  }
516 
517  public static implicit operator Microsoft.Xna.Framework.Vector3( Vector v )
518  {
519  return new Microsoft.Xna.Framework.Vector3( (float)v.X, (float)v.Y, 0 );
520  }
521  }
522 }
Jypeli.Vector.Min
static Vector Min(params Vector[] vectors)
Palauttaa lyhimmän vektorin.
Definition: Vector.cs:231
AdvanceMath.MathHelper.Sqrt
static Scalar Sqrt(Scalar d)
Definition: MathHelper.cs:314
Jypeli.Vector.LeftNormal
Vector LeftNormal
Vasen normaali.
Definition: Vector.cs:89
Jypeli.Matrix
Microsoft.Xna.Framework.Matrix Matrix
Definition: Mouse.cs:36
Jypeli.Vector.Equals
override bool Equals(object obj)
Definition: Vector.cs:442
Microsoft.Xna
Definition: JypeliContentManager.cs:6
Jypeli.Vector.GetHashCode
override int GetHashCode()
Definition: Vector.cs:437
Jypeli.Vector.One
static readonly Vector One
Yksikkövektori.
Definition: Vector.cs:68
Jypeli.Vector.UnitY
static readonly Vector UnitY
Pystysuuntainen yksikkövektori (pituus 1, suunta ylös).
Definition: Vector.cs:78
Jypeli.Vector.X
double X
Definition: Vector.cs:312
Jypeli.Vector.Zero
static readonly Vector Zero
Nollavektori.
Definition: Vector.cs:63
Jypeli.Vector.operator-
static Vector operator-(Vector left, Vector right)
Definition: Vector.cs:398
Jypeli.Vector.DotProduct
static double DotProduct(Vector left, Vector right)
Pistetulo.
Definition: Vector.cs:147
Jypeli
Definition: Automobile.cs:5
Jypeli.Vector.Diagonal
static readonly Vector Diagonal
Diagonaalivektori (1,1)
Definition: Vector.cs:83
Microsoft
Definition: JypeliContentManager.cs:6
Microsoft.Xna.Framework
Definition: JypeliContentManager.cs:6
Jypeli.Vector.Distance
double Distance(Vector2D vector)
Definition: Vector.cs:176
Jypeli.Vector.UnitX
static readonly Vector UnitX
Vaakasuuntainen yksikkövektori (pituus 1, suunta oikealle).
Definition: Vector.cs:73
Jypeli.Vector.RightNormal
Vector RightNormal
Oikea normaali.
Definition: Vector.cs:97
AdvanceMath.MathHelper
Definition: MathHelper.cs:38
Jypeli.Vector.Average
static Vector Average(IEnumerable< Vector > vectors)
Palauttaa kahden tai useamman vektorin keskiarvon.
Definition: Vector.cs:277
Jypeli.Vector.Max
static Vector Max(params Vector[] vectors)
Palauttaa pisimmän vektorin.
Definition: Vector.cs:254
Jypeli.Vector.Vector
Vector(double X, double Y)
Luo uuden vektorin komponenteista.
Definition: Vector.cs:336
Jypeli.Vector.ScalarProjection
double ScalarProjection(Vector unitVector)
Definition: Vector.cs:181
Jypeli.Angle.Radians
double Radians
Palauttaa tai asettaa kulman radiaaneina.
Definition: Angle.cs:85
Jypeli.Vector.ToString
string ToString(IFormatProvider formatProvider)
Definition: Vector.cs:365
Jypeli.Vector.operator*
static Vector operator*(Vector source, double scalar)
Definition: Vector.cs:406
Jypeli.Vector.ComponentProduct
static Vector ComponentProduct(Vector a, Vector b)
Kertoo kaksi vektoria komponenteittain.
Definition: Vector.cs:171
Jypeli.Vector.CrossProduct
static double CrossProduct(Vector left, Vector right)
Ristitulo. Palauttaa kohtisuoraan vektoreita vastaan olevan uuden vektorin pituuden....
Definition: Vector.cs:160
Jypeli.Vector.FromLengthAndAngle
static Vector FromLengthAndAngle(double length, Angle angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:117
AdvanceMath.Vector2D.X
Scalar X
This is the X value. (Usually represents a horizontal position or direction.)
Definition: Vector2D.cs:796
Jypeli.Vector.Transform
Vector Transform(Matrix matrix)
Kertoo vektorin matriisilla.
Definition: Vector.cs:208
Jypeli.Vector.Angle
Angle Angle
Kulma radiaaneina.
Definition: Vector.cs:346
Jypeli.Angle.FromRadians
static Angle FromRadians(double radian)
Luo kulman annettujen radiaanien mukaan.
Definition: Angle.cs:315
Jypeli.Vector.FromAngle
static Vector FromAngle(Angle angle)
Luo vektorin kulman perusteella yksikköpituudella.
Definition: Vector.cs:125
Jypeli.Vector.operator+
static Vector operator+(Vector left, Vector right)
Definition: Vector.cs:390
Matrix
Microsoft.Xna.Framework.Matrix Matrix
Definition: Vector.cs:35
Jypeli.Vector.Distance
static double Distance(Vector p1, Vector p2)
Etäisyys kahden pisteen välillä.
Definition: Vector.cs:133
Jypeli.Vector.Transpose
Vector Transpose()
Palauttaa uuden vektorin, jossa x ja y on vaihdettu keskenään.
Definition: Vector.cs:221
Jypeli.Vector.operator!=
static bool operator!=(Vector left, Vector right)
Definition: Vector.cs:487
Jypeli.Vector.MagnitudeSquared
double MagnitudeSquared
Vektorin pituuden neliö.
Definition: Vector.cs:327
Jypeli.Vector.FromLengthAndAngle
static Vector FromLengthAndAngle(double length, double angle)
Luo vektorin pituuden ja kulman perusteella.
Definition: Vector.cs:106
Jypeli.Vector.Magnitude
double Magnitude
Vektorin pituus.
Definition: Vector.cs:319
Jypeli.Vector
2D-vektori.
Definition: Vector.cs:59
System
Definition: CFFauxAttributes.cs:29
Jypeli.Vector.Parse
static Vector Parse(string vectorStr, IFormatProvider formatProvider)
Definition: Vector.cs:377
Jypeli.Vector.operator/
static Vector operator/(Vector source, double scalar)
Definition: Vector.cs:419
Jypeli.Vector.operator==
static bool operator==(Vector left, Vector right)
Definition: Vector.cs:477
Jypeli.ObjectHelper.GetHashCode
static int GetHashCode(params object[] objects)
Palauttaa hajautuskoodin usean olion kokoelmalle.
Definition: ObjectHelper.cs:13
AdvanceMath.Vector4D
A Vector with 4 dimensions.
Definition: Vector4D.cs:48
AdvanceMath.Vector3D
A Vector with 3 dimensions.
Definition: Vector3D.cs:47
AdvanceMath.Vector2D
This is the Vector Class.
Definition: Vector2D.cs:50
AdvanceMath.Vector2D.Y
Scalar Y
This is the Y value. (Usually represents a vertical position or direction.)
Definition: Vector2D.cs:805
Jypeli.Vector.ToString
override string ToString()
Vektori merkkijonona muodossa (x,y)
Definition: Vector.cs:360
Jypeli.Vector.Project
Vector Project(Vector to)
Laskee ja palauttaa tämän pisteen etäisyyden toiseen pisteeseen.
Definition: Vector.cs:189
Jypeli.Vector.Normalize
Vector Normalize()
Palauttaa uuden vektorin, jonka suunta pysyy samana, mutta pituudeksi tulee 1.0.
Definition: Vector.cs:198
AdvanceMath
Definition: Clamped.cs:36
Jypeli.ObjectHelper
Apuluokka kaikille olioille
Definition: ObjectHelper.cs:7
Jypeli.Vector.Y
double Y
Definition: Vector.cs:313
Jypeli.Vector.Average
static Vector Average(params Vector[] vectors)
Palauttaa kahden tai useamman vektorin keskiarvon.
Definition: Vector.cs:298
Jypeli.Vector.Parse
static Vector Parse(string vectorStr)
Definition: Vector.cs:372
Jypeli.Angle
Suuntakulma (rajoitettu -180 ja 180 asteen välille) asteina ja radiaaneina. Tietoja kulmasta: http://...
Definition: Angle.cs:40