Utilities: Integer Vectors

0

Another datatype, or two if you want. Integer Vectors in 2D and 3D. They work nearly identically to the standard Vector2 and Vector3 types, but use integers only. I did not write these myself. The original idea was a request in the Unity3D forums and the original implementation was done there by Lysander. I only made some minor changes to it.

<pre>using UnityEngine;
using System;

// Integer Vector2
// © Lysander from the Unity3D Forums

namespace Utilities {
	[Serializable]
	public struct Int2 : IEquatable<Int2> {
		// Properties
		public int x { get; set; }
		public int y { get; set; }

		public Int2 normalized {
			get {
				Int2 newVector = new Int2(x, y);
				newVector.Normalize();
				return newVector;
			}
		}

		public float magnitude { get { return Mathf.Sqrt(x * x + y * y); } }

		public float sqrMagnitude { get { return x * x + y * y; } }

		// Indexer
		public int this[int index] {
			get {
				switch(index) {
					case 0:
						return x;
					case 1:
						return y;
					default:
						throw new IndexOutOfRangeException("Invalid Int2 index");
				}
			}

			set {
				switch(index) {
					case 0:
						x = value;
						break;
					case 1:
						y = value;
						break;
					default:
						throw new IndexOutOfRangeException("Invalid Int2 index");
				}
			}
		}

		// Constructors
		public Int2(int vX, int vY) : this() {
			x = vX;
			y = vY;
		}

		// Static Conversions From Other Types
		public static Int2 FromVector2(Vector2 vector2) {
			return new Int2 {
				x = Mathf.RoundToInt(vector2.x),
				y = Mathf.RoundToInt(vector2.y)
			};
		}

		public static Int2 FromVector3(Vector3 vector3) {
			return new Int2 {
				x = Mathf.RoundToInt(vector3.x),
				y = Mathf.RoundToInt(vector3.y)
			};
		}

		public static Int2 FromInt3(Int3 int3) {
			return new Int2 {
				x = int3.x,
				y = int3.y
			};
		}

		// Conversions To Other Types
		public Vector2 ToVector2() { return new Vector2(x, y); }

		public Vector3 ToVector3() { return new Vector3(x, y, 0f); }

		public Int3 ToInt3() { return new Int3(x, y, 0); }

		// Static Int2 Values
		public static readonly Int2 zero = new Int2(0, 0);

		public static readonly Int2 up = new Int2(0, 1);

		public static readonly Int2 down = new Int2(0, -1);

		public static readonly Int2 right = new Int2(1, 0);

		public static readonly Int2 left = new Int2(-1, 0);

		public static readonly Int2 one = new Int2(1, 1);

		// Other Static Functions
		public static Int2 Scale(Int2 a, Int2 b) {
			return new Int2(a.x * b.x, a.y * b.y);
		}

		public static Int2 Reflect(Int2 inDirection, Int2 inNormal) {
			return -2f * Dot(inNormal, inDirection) * inNormal + inDirection;
		}

		public static float Dot(Int2 a, Int2 b) {
			return a.x * b.x + a.y * b.y;
		}

		public static float Angle(Int2 from, Int2 to) {
			return Mathf.Acos(Mathf.Clamp(Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f;
		}

		public static float Distance(Int2 a, Int2 b) {
			return (a - b).magnitude;
		}

		public static Int2 ClampMagnitude(Int2 vector, float maxLength) {
			if(vector.sqrMagnitude > maxLength * maxLength) {
				return vector.normalized * maxLength;
			}
			return vector;
		}

		public static Int2 Min(Int2 a, Int2 b) {
			return new Int2(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y));
		}

		public static Int2 Max(Int2 a, Int2 b) {
			return new Int2(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y));
		}

		// Other Functions
		public void Set(int vX, int vY) {
			x = vX;
			y = vY;
		}

		public void Scale(Int2 scale) {
			x *= scale.x;
			y *= scale.y;
		}

		public void Normalize() {
			float num = magnitude;
			if(num > 1E-05f)
				this /= num;
			else
				this = zero;
		}

		public void ShiftAll(int amount) {
			x += amount;
			y += amount;
		}

		public void ShiftAll(float amount) {
			ShiftAll(Mathf.RoundToInt(amount));
		}

		// Int2 & Int2 Operator Overloads
		public static Int2 operator +(Int2 a, Int2 b) {
			return new Int2(a.x + b.x, a.y + b.y);
		}

		public static Int2 operator -(Int2 a, Int2 b) {
			return new Int2(a.x - b.x, a.y - b.y);
		}

		public static Int2 operator -(Int2 a) {
			return new Int2(-a.x, -a.y);
		}

		public static Int2 operator *(Int2 a, Int2 b) {
			return new Int2(a.x * b.x, a.y * b.y);
		}

		public static Int2 operator /(Int2 a, Int2 b) {
			return new Int2(a.x / b.x, a.y / b.y);
		}

		// Int2 & Int Operator Overloads
		public static Int2 operator *(Int2 a, int d) {
			return new Int2(a.x * d, a.y * d);
		}

		public static Int2 operator *(Int2 a, float d) {
			return new Int2(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d));
		}

		public static Int2 operator *(int d, Int2 a) {
			return new Int2(a.x * d, a.y * d);
		}

		public static Int2 operator *(float d, Int2 a) {
			return new Int2(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d));
		}

		public static Int2 operator /(Int2 a, int d) {
			return new Int2(a.x / d, a.y / d);
		}

		public static Int2 operator /(Int2 a, float d) {
			return new Int2(Mathf.RoundToInt(a.x / d), Mathf.RoundToInt(a.y / d));
		}

		// Equality and Inequality Operator Overloads
		public static bool operator ==(Int2 i1, Int2 i2) {
			return i1.x.Equals(i2.x) && i1.y.Equals(i2.y);
		}

		public static bool operator !=(Int2 i1, Int2 i2) {
			return !i1.x.Equals(i2.x) || !i1.y.Equals(i2.y);
		}

		// miscellaneous overrides
		public override bool Equals(object obj) {
			if(obj is Int2) {
				Int2 vector = (Int2)obj;
				return x.Equals(vector.x) && y.Equals(vector.y);
			}
			return false;
		}

		public bool Equals(Int2 vector) {
			return x.Equals(vector.x) && y.Equals(vector.y);
		}

		public override int GetHashCode() {
			return x.GetHashCode() ^ y.GetHashCode() << 2;
		}

		public override string ToString() {
			return "(" + x + ", " + y + ")";
		}

		public static implicit operator Vector2(Int2 vector) {
			return new Vector2(vector.x, vector.y);
		}
	}
}
using UnityEngine;
using System;

// Integer Vector3
// © Lysander from the Unity3D Forums

namespace Utilities {
	[Serializable]
	public struct Int3 : IEquatable<Int3> {
		// Properties
		public int x { get; set; }
		public int y { get; set; }
		public int z { get; set; }

		public Int3 normalized {
			get {
				Int3 newVector = new Int3(x, y, z);
				newVector.Normalize();
				return newVector;
			}
		}

		public float magnitude { get { return Mathf.Sqrt(x * x + y * y + z * z); } }

		public float sqrMagnitude { get { return x * x + y * y + z * z; } }

		// Indexer
		public int this[int index] {
			get {
				switch(index) {
					case 0:
						return x;
					case 1:
						return y;
					case 2:
						return z;
					default:
						throw new IndexOutOfRangeException("Invalid Int3 index!");
				}
			}

			set {
				switch(index) {
					case 0:
						x = value;
						break;
					case 1:
						y = value;
						break;
					case 2:
						z = value;
						break;
					default:
						throw new IndexOutOfRangeException("Invalid Int3 index!");
				}
			}
		}

		// Constructors
		public Int3(int vX, int vY, int vZ) : this() {
			x = vX;
			y = vY;
			z = vZ;
		}

		public Int3(int vX, int vY) : this() {
			x = vX;
			y = vY;
			z = 0;
		}

		// Static Conversions From Other Types
		public static Int3 FromVector2(Vector2 vector2) {
			return new Int3 {
				x = Mathf.RoundToInt(vector2.x),
				y = Mathf.RoundToInt(vector2.y)
			};
		}

		public static Int3 FromVector3(Vector3 vector3) {
			return new Int3 {
				x = Mathf.RoundToInt(vector3.x),
				y = Mathf.RoundToInt(vector3.y),
				z = Mathf.RoundToInt(vector3.z)
			};
		}

		public static Int3 FromInt2(Int2 int2) {
			return new Int3 {
				x = int2.x,
				y = int2.y
			};
		}

		// Conversions To Other Types
		public Vector2 ToVector2() { return new Vector2(x, y); }

		public Vector3 ToVector3() { return new Vector3(x, y, z); }

		public Int2 ToInt2() { return new Int2(x, y); }

		// Static Int2 Values
		public static readonly Int3 zero = new Int3(0, 0, 0);

		public static readonly Int3 forward = new Int3(0, 0, 1);

		public static readonly Int3 back = new Int3(0, 0, -1);

		public static readonly Int3 up = new Int3(0, 1, 0);

		public static readonly Int3 down = new Int3(0, -1, 0);

		public static readonly Int3 right = new Int3(1, 0, 0);

		public static readonly Int3 left = new Int3(-1, 0, 0);

		public static readonly Int3 one = new Int3(1, 1, 1);

		// Other Static Functions
		public static Int3 Scale(Int3 a, Int3 b) {
			return new Int3(a.x * b.x, a.y * b.y, a.z * b.z);
		}

		public static Int3 Cross(Int3 a, Int3 b) {
			return new Int3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
		}

		public static Int3 Reflect(Int3 inDirection, Int3 inNormal) {
			return -2f * Dot(inNormal, inDirection) * inNormal + inDirection;
		}

		public static float Dot(Int3 a, Int3 b) {
			return a.x * b.x + a.y * b.y + a.z * b.z;
		}

		public static float Angle(Int3 from, Int3 to) {
			return Mathf.Acos(Mathf.Clamp(Dot(from.normalized, to.normalized), -1f, 1f)) * 57.29578f;
		}

		public static float Distance(Int3 a, Int3 b) {
			Int3 vector = new Int3(a.x - b.x, a.y - b.y, a.z - b.z);
			return Mathf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
		}

		public static Int3 ClampMagnitude(Int3 vector, float maxLength) {
			if(vector.sqrMagnitude > maxLength * maxLength) {
				return vector.normalized * maxLength;
			}
			return vector;
		}

		public static Int3 Min(Int3 a, Int3 b) {
			return new Int3(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y), Mathf.Min(a.z, b.z));
		}

		public static Int3 Max(Int3 a, Int3 b) {
			return new Int3(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y), Mathf.Max(a.z, b.z));
		}

		// Other Functions
		public void Set(int vX, int vY, int vZ) {
			x = vX;
			y = vY;
			z = vZ;
		}

		public void Scale(Int3 scale) {
			x *= scale.x;
			y *= scale.y;
			z *= scale.z;
		}

		public void Normalize() {
			float num = magnitude;
			if(num > 1E-05f)
				this /= num;
			else
				this = zero;
		}

		public void ShiftAll(int amount) {
			x += amount;
			y += amount;
			z += amount;
		}

		public void ShiftAll(float amount) {
			ShiftAll(Mathf.RoundToInt(amount));
		}

		// Int2 & Int2 Operator Overloads
		public static Int3 operator +(Int3 a, Int3 b) {
			return new Int3(a.x + b.x, a.y + b.y, a.z + b.z);
		}

		public static Int3 operator -(Int3 a, Int3 b) {
			return new Int3(a.x - b.x, a.y - b.y, a.z - b.z);
		}

		public static Int3 operator -(Int3 a) {
			return new Int3(-a.x, -a.y, -a.z);
		}

		public static Int3 operator *(Int3 a, Int3 b) {
			return new Int3(a.x * b.x, a.y * b.y, a.z * b.z);
		}

		public static Int3 operator /(Int3 a, Int3 b) {
			return new Int3(a.x / b.x, a.y / b.y, a.z / b.z);
		}

		// Int2 & Int Operator Overloads
		public static Int3 operator *(Int3 a, int d) {
			return new Int3(a.x * d, a.y * d, a.z * d);
		}

		public static Int3 operator *(Int3 a, float d) {
			return new Int3(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d), Mathf.RoundToInt(a.z * d));
		}

		public static Int3 operator *(int d, Int3 a) {
			return new Int3(a.x * d, a.y * d, a.z * d);
		}

		public static Int3 operator *(float d, Int3 a) {
			return new Int3(Mathf.RoundToInt(a.x * d), Mathf.RoundToInt(a.y * d), Mathf.RoundToInt(a.z * d));
		}

		public static Int3 operator /(Int3 a, int d) {
			return new Int3(a.x / d, a.y / d, a.z / d);
		}

		public static Int3 operator /(Int3 a, float d) {
			return new Int3(Mathf.RoundToInt(a.x / d), Mathf.RoundToInt(a.y / d), Mathf.RoundToInt(a.z / d));
		}

		// Equality and Inequality Operator Overloads
		public static bool operator ==(Int3 a, Int3 b) {
			return a.x.Equals(b.x) && a.y.Equals(b.y) && a.z.Equals(b.z);
		}

		public static bool operator !=(Int3 a, Int3 b) {
			return !a.x.Equals(b.x) || !a.y.Equals(b.y) || !a.z.Equals(b.z);
		}

		// Overrides & Implementations
		public override bool Equals(object obj) {
			if(obj is Int3) {
				Int3 vector = (Int3)obj;
				return x.Equals(vector.x) && y.Equals(vector.y) && z.Equals(vector.z);
			}
			return false;
		}

		public bool Equals(Int3 vector) {
			return x.Equals(vector.x) && y.Equals(vector.y) && z.Equals(vector.z);
		}

		public override int GetHashCode() {
			return x.GetHashCode() ^ y.GetHashCode() << 2 ^ z.GetHashCode() >> 2;
		}

		public override string ToString() {
			return "(" + x + ", " + y + ", " + z + ")";
		}

		public static implicit operator Vector3(Int3 vector) {
			return new Vector3(vector.x, vector.y, vector.z);
		}
	}
}

Comments

Your email address will not be published. Required fields are marked *