Utilities: Integer Vectors

11

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 *