//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System;
using System.Runtime.InteropServices;
namespace BansheeEngine
{
/** @addtogroup Math
* @{
*/
///
/// A two dimensional vector.
///
[StructLayout(LayoutKind.Sequential), SerializeObject]
public struct Vector2 // Note: Must match C++ struct Vector2
{
public float x;
public float y;
public static readonly Vector2 Zero = new Vector2(0.0f, 0.0f);
public static readonly Vector2 One = new Vector2(1.0f, 1.0f);
public static readonly Vector2 XAxis = new Vector2(1.0f, 0.0f);
public static readonly Vector2 YAxis = new Vector2(0.0f, 1.0f);
///
/// Accesses a specific component of the vector.
///
/// Index of the component.
/// Value of the specific component.
public float this[int index]
{
get
{
switch (index)
{
case 0:
return x;
case 1:
return y;
default:
throw new IndexOutOfRangeException("Invalid Vector2 index.");
}
}
set
{
switch (index)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
default:
throw new IndexOutOfRangeException("Invalid Vector2 index.");
}
}
}
///
/// Returns a normalized copy of the vector.
///
public Vector2 Normalized
{
get
{
return Normalize(this);
}
}
///
/// Returns the length of the vector.
///
public float Length
{
get
{
return MathEx.Sqrt(x * x + y * y);
}
}
///
/// Returns the squared length of the vector.
///
public float SqrdLength
{
get
{
return (x * x + y * y);
}
}
///
/// Creates a new two dimensional vector.
///
/// X coordinate.
/// Y coordinate.
public Vector2(float x, float y)
{
this.x = x;
this.y = y;
}
public static Vector2 operator+ (Vector2 a, Vector2 b)
{
return new Vector2(a.x + b.x, a.y + b.y);
}
public static Vector2 operator- (Vector2 a, Vector2 b)
{
return new Vector2(a.x - b.x, a.y - b.y);
}
public static Vector2 operator- (Vector2 v)
{
return new Vector2(-v.x, -v.y);
}
public static Vector2 operator *(Vector2 a, Vector2 b)
{
return new Vector2(a.x * b.x, a.y * b.y);
}
public static Vector2 operator* (Vector2 v, float d)
{
return new Vector2(v.x * d, v.y * d);
}
public static Vector2 operator* (float d, Vector2 v)
{
return new Vector2(v.x * d, v.y * d);
}
public static Vector2 operator/ (Vector2 v, float d)
{
return new Vector2(v.x / d, v.y / d);
}
public static bool operator== (Vector2 lhs, Vector2 rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
}
public static bool operator!= (Vector2 lhs, Vector2 rhs)
{
return !(lhs == rhs);
}
///
/// Scales one vector by another.
///
/// First two dimensional vector.
/// Second two dimensional vector.
/// One vector scaled by another.
public static Vector2 Scale(Vector2 a, Vector2 b)
{
return new Vector2(a.x * b.x, a.y * b.y);
}
///
/// Normalizes the provided vector and returns the normalized copy.
///
/// Vector to normalize.
/// Normalized copy of the vector.
public static Vector2 Normalize(Vector2 value)
{
float num = Magnitude(value);
if (num > 9.999999E-06f)
return value / num;
return Zero;
}
///
/// Calculates the inner product of the two vectors.
///
/// First two dimensional vector.
/// Second two dimensional vector.
/// Inner product between the two vectors.
public static float Dot(Vector2 lhs, Vector2 rhs)
{
return lhs.x * rhs.x + lhs.y * rhs.y;
}
///
/// Calculates the distance between two points.
///
/// First two dimensional point.
/// Second two dimensional point.
/// Distance between the two points.
public static float Distance(Vector2 a, Vector2 b)
{
Vector2 vector2 = new Vector2(a.x - b.x, a.y - b.y);
return MathEx.Sqrt(vector2.x * vector2.x + vector2.y * vector2.y);
}
///
/// Calculates the magnitude of the provided vector.
///
/// Vector to calculate the magnitude for.
/// Magnitude of the vector.
public static float Magnitude(Vector2 v)
{
return MathEx.Sqrt(v.x * v.x + v.y * v.y);
}
///
/// Calculates the squared magnitude of the provided vector.
///
/// Vector to calculate the magnitude for.
/// Squared magnitude of the vector.
public static float SqrMagnitude(Vector2 v)
{
return (v.x * v.x + v.y * v.y);
}
///
/// Returns the maximum of all the vector components as a new vector.
///
/// First vector.
/// Second vector.
/// Vector consisting of maximum components of the first and second vector.
public static Vector2 Max(Vector2 a, Vector2 b)
{
return new Vector2(MathEx.Max(a.x, b.x), MathEx.Max(a.y, b.y));
}
///
/// Returns the minimum of all the vector components as a new vector.
///
/// First vector.
/// Second vector.
/// Vector consisting of minimum components of the first and second vector.
public static Vector2 Min(Vector2 a, Vector2 b)
{
return new Vector2(MathEx.Min(a.x, b.x), MathEx.Min(a.y, b.y));
}
///
/// Scales the components of the vector by specified scale factors.
///
/// Scale factors to multiply components by.
public void Scale(Vector2 scale)
{
x *= scale.x;
y *= scale.y;
}
///
/// Normalizes the vector.
///
public void Normalize()
{
float num = Magnitude(this);
if (num > 9.999999E-06f)
this /= num;
else
this = Zero;
}
///
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode() << 2;
}
///
public override bool Equals(object other)
{
if (!(other is Vector2))
return false;
Vector2 vec = (Vector2)other;
if (x.Equals(vec.x) && y.Equals(vec.y))
return true;
return false;
}
///
public override string ToString()
{
return "(" + x + ", " + y + ")";
}
}
/** @} */
}