## Utilities: Integer Vectors

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);
}
}
}
```