diff --git a/PveTeam.Math/Vector3D.cs b/PveTeam.Math/Vector3D.cs index 51004a0..b125e5a 100644 --- a/PveTeam.Math/Vector3D.cs +++ b/PveTeam.Math/Vector3D.cs @@ -5,7 +5,7 @@ using System.Text; namespace PveTeam.Mathematics { - public struct Vector3D : IEquatable, IFormattable + public struct Vector3D : IEquatable, IFormattable { public Double X, Y, Z; @@ -206,12 +206,12 @@ namespace PveTeam.Mathematics public override bool Equals(object obj) { - if (!(obj is Vector3)) + if (!(obj is Vector3D)) return false; - return Equals((Vector3)obj); + return Equals((Vector3D)obj); } - public bool Equals(Vector3 other) + public bool Equals(Vector3D other) => X == other.X && Y == other.Y && Z == other.Z; #endregion diff --git a/PveTeam.Math/Vector3I.cs b/PveTeam.Math/Vector3I.cs index 6e5e820..23495e4 100644 --- a/PveTeam.Math/Vector3I.cs +++ b/PveTeam.Math/Vector3I.cs @@ -1,9 +1,141 @@ using System; +using System.Globalization; +using System.Numerics; +using System.Text; namespace PveTeam.Mathematics { - public struct Vector3I + public struct Vector3I : IEquatable, IFormattable { public Int32 X, Y, Z; + + #region Static fields + public static Vector3I Zero => new Vector3I(0); + public static Vector3I One => new Vector3I(1); + public static Vector3I UnitX => new Vector3I(1, 0, 0); + public static Vector3I UnitY => new Vector3I(0, 1, 0); + public static Vector3I UnitZ => new Vector3I(0, 0, 1); + #endregion + + #region Constructors + public Vector3I(Int32 value) : this(value, value, value) { } + + public Vector3I(Vector3 value) : this((Int32)value.X, (Int32)value.Y, (Int32)value.Z) { } + + public Vector3I(Single x, Single y, Single z) : this((Int32)x, (Int32)y, (Int32)z) { } + + public Vector3I(Vector3D value) : this((Int32)value.X, (Int32)value.Y, (Int32)value.Z) { } + + public Vector3I(Int32 x, Int32 y, Int32 z) + { + X = x; + Y = y; + Z = z; + } + #endregion + + #region Instance methods + public readonly Single Length() + => MathF.Sqrt(LengthSquared()); + + public readonly Single LengthSquared() + => X * X + Y * Y + Z * Z; + #endregion + + #region Static methods + + public static Single Distance(Vector3I value1, Vector3I value2) + => (value1 - value2).Length(); + + public static Single DistanceSquared(Vector3I value1, Vector3I value2) + => (value1 - value2).LengthSquared(); + + public static Vector3I Normalize(Vector3I value) + => value / value.Length(); + #endregion + + #region Operators + public static Vector3I operator +(Vector3I left, Vector3I right) + => new Vector3I(left.X + right.X, left.Y + right.Y, left.Z + right.Z); + public static Vector3I operator -(Vector3I left, Vector3I right) + => new Vector3I(left.X - right.X, left.Y - right.Y, left.Z - right.Z); + public static Vector3I operator *(Vector3I left, Vector3I right) + => new Vector3I(left.X * right.X, left.Y * right.Y, left.Z * right.Z); + public static Vector3I operator *(Vector3I left, Single right) + => left * new Vector3I((int)right); + public static Vector3I operator *(Single left, Vector3I right) + => new Vector3I((int)left) * right; + public static Vector3I operator /(Vector3I left, Vector3I right) + => new Vector3I(left.X / right.X, left.Y / right.Y, left.Z / right.Z); + public static Vector3I operator /(Vector3I left, Single right) + { + Single invert = 1.0f / right; + return new Vector3I(left.X * invert, left.Y * invert, left.Z * invert); + } + public static Vector3I operator -(Vector3I value) + => Zero - value; + public static bool operator ==(Vector3I left, Vector3I right) + => left.X == right.X && left.Y == right.Y && left.Z == right.Z; + public static bool operator !=(Vector3I left, Vector3I right) + => left.X != right.X || left.Y != right.Y || left.Z != right.Z; + + #endregion + + #region Operator methods + public static Vector3I Add(Vector3I left, Vector3I right) + => left + right; + public static Vector3I Subtract(Vector3I left, Vector3I right) + => left - right; + public static Vector3I Multiply(Vector3I left, Vector3I right) + => left * right; + public static Vector3I Multiply(Vector3I left, int right) + => left * right; + public static Vector3I Multiply(int left, Vector3I right) + => left * right; + public static Vector3I Divide(Vector3I left, Vector3I right) + => left / right; + public static Vector3I Divide(Vector3I left, int right) + => left / right; + #endregion + + #region Equals + + public override int GetHashCode() + => X.GetHashCode() ^ Y.GetHashCode() << 2 ^ Z.GetHashCode() >> 2; + + public override bool Equals(object obj) + { + if (!(obj is Vector3I)) + return false; + return Equals((Vector3I)obj); + } + + public bool Equals(Vector3I other) + => X == other.X && Y == other.Y && Z == other.Z; + #endregion + + #region Formatting + public string ToString(string format, IFormatProvider formatProvider) + { + StringBuilder sb = new StringBuilder(); + string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator; + sb.Append('<'); + sb.Append(((IFormattable)this.X).ToString(format, formatProvider)); + sb.Append(separator); + sb.Append(' '); + sb.Append(((IFormattable)this.Y).ToString(format, formatProvider)); + sb.Append(separator); + sb.Append(' '); + sb.Append(((IFormattable)this.Z).ToString(format, formatProvider)); + sb.Append('>'); + return sb.ToString(); + } + + public override string ToString() + => ToString("G", CultureInfo.CurrentCulture); + + public string ToString(string format) + => ToString(format, CultureInfo.CurrentCulture); + #endregion } }