Source

SharpHammer / SharpHammer / Vec2.cs

using System;
using System.Runtime.InteropServices;

namespace SharpHammer
{
	[StructLayout(LayoutKind.Sequential)]
	public struct Vec2
	{
		public Vec2(float x, float y)
		{
			X = x;
			Y = y;
		}

		/// <summary>
		/// Normalize this Vec2.
		/// </summary>
		public void Normalize()
		{
			float invlength = 1.0f / Length;
			X *= invlength;
			Y *= invlength;
		}

		public System.Drawing.PointF ToPointF()
		{
			return new System.Drawing.PointF(X, Y);
		}

		public override string ToString()
		{
			return string.Format("X:{0} Y:{1}", X, Y);
		}

		/// <summary>
		/// Returns dot product of this two Vec2.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static float Dot(Vec2 a, Vec2 b)
		{
			return a.X * b.X + a.Y * b.Y;
		}

		/// <summary>
		/// Linearly interpolate from a to b.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="t"></param>
		/// <returns></returns>
		public static Vec2 Lerp(Vec2 a, Vec2 b, float t)
		{
			return new Vec2((b.X - a.X) * t + a.X, (b.Y - a.Y) * t + a.Y);
		}

		/// <summary>
		/// Returns distance between a to b.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static float Distance(Vec2 a, Vec2 b)
		{
			float dx = a.X - b.X;
			float dy = a.Y - b.Y;
			return (float)Math.Sqrt(dx * dx + dy * dy);
		}

		/// <summary>
		/// Returns Squared distance between a to b.
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static float SqrDistance(Vec2 a, Vec2 b)
		{
			float dx = a.X - b.X;
			float dy = a.Y - b.Y;
			return dx * dx + dy * dy;
		}

		/// <summary>
		/// Returns Vec2 from system.drawing.PointF
		/// </summary>
		/// <param name="pnt"></param>
		/// <returns></returns>
		public static Vec2 FromPointF(System.Drawing.PointF pnt)
		{
			return new Vec2(pnt.X, pnt.Y);
		}

		public static Vec2 operator +(Vec2 a, Vec2 b)
		{
			a.X += b.X;
			a.Y += b.Y;
			return a;
		}

		public static Vec2 operator -(Vec2 a, Vec2 b)
		{
			a.X -= b.X;
			a.Y -= b.Y;
			return a;
		}

		public static Vec2 operator *(Vec2 a, Vec2 b)
		{
			a.X *= b.X;
			a.Y *= b.Y;
			return a;
		}

		public static Vec2 operator *(Vec2 a, float b)
		{
			a.X *= b;
			a.Y *= b;
			return a;
		}

		public static Vec2 operator *(float a, Vec2 b)
		{
			b.X *= a;
			b.Y *= a;
			return b;
		}

		public static Vec2 operator /(Vec2 a, Vec2 b)
		{
			a.X /= b.X;
			a.Y /= b.Y;
			return a;
		}

		public static Vec2 operator /(Vec2 a, float b)
		{
			float inv = 1.0f / b;
			a.X *= inv;
			a.Y *= inv;
			return a;
		}

		/// <summary>
		/// Gets the length of this Vec2.
		/// </summary>
		public float Length
		{
			get
			{
				return (float)Math.Sqrt(X * X + Y * Y);
			}
		}

		/// <summary>
		/// Gets the squared length of this Vec2.
		/// </summary>
		public float SqrLength
		{
			get
			{
				return X * X + Y * Y;
			}
		}

		/// <summary>
		/// Normalized version of this Vec2.
		/// </summary>
		public Vec2 Normalized
		{
			get
			{
				Vec2 tmp = this;
				tmp.Normalize();
				return tmp;
			}
		}

		public float X;
		public float Y;

		public static readonly Vec2 Zero = new Vec2(0, 0);
		public static readonly Vec2 One = new Vec2(1, 1);
	}
}