using System; namespace Assets.AR { public struct Vector3d : IEquatable { private static readonly Vector3d ZeroVector = new Vector3d(0.0, 0.0, 0.0); private static readonly Vector3d OneVector = new Vector3d(1.0, 1.0, 1.0); public double x; public double y; public double z; public Vector3d(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public Vector3d(double[] c) { this.x = c[0]; this.y = c[1]; this.z = c[2]; } public static Vector3d Zero => Vector3d.ZeroVector; public static Vector3d One => Vector3d.OneVector; public Vector3d Normalized => Vector3d.Normalize(this); public double this[int index] { get { switch (index) { case 0: return this.x; case 1: return this.y; case 2: return this.z; default: throw new IndexOutOfRangeException("Invalid Vector3d index!"); } } set { switch (index) { case 0: this.x = value; break; case 1: this.y = value; break; case 2: this.z = value; break; default: throw new IndexOutOfRangeException("Invalid Vector3d index!"); } } } public void Set(double newX, double newY, double newZ) { this.x = newX; this.y = newY; this.z = newZ; } public static double Magnitude(Vector3d v) => Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); public static double SqrMagnitude(Vector3d v) => v.x * v.x + v.y * v.y + v.z * v.z; public static Vector3d Lerp(Vector3d a, Vector3d b, double t) => new Vector3d((1.0 - t) * a.x + t * b.x, (1.0 - t) * a.y + t * b.y, (1.0 - t) * a.z + t * b.z); public static Vector3d LerpClamped(Vector3d a, Vector3d b, double t) { t = PFMath.Clamp01(t); return Vector3d.Lerp(a, b, t); } public static Vector3d Scale(Vector3d a, Vector3d b) => new Vector3d(a.x * b.x, a.y * b.y, a.z * b.z); public void Scale(Vector3d scale) { this.x *= scale.x; this.y *= scale.y; this.z *= scale.z; } public static Vector3d Cross(Vector3d lhs, Vector3d rhs) => new Vector3d(lhs.y * rhs.z - lhs.z * rhs.y, lhs.z * rhs.x - lhs.x * rhs.z, lhs.x * rhs.y - lhs.y * rhs.x); public override int GetHashCode() => this.x.GetHashCode() ^ this.y.GetHashCode() << 2 ^ this.z.GetHashCode() >> 2; public override bool Equals(object other) => other is Vector3d other1 && this.Equals(other1); public bool Equals(Vector3d other) => this == other; public static Vector3d Normalize(Vector3d value) { double num = Vector3d.Magnitude(value); return num > 0.0 ? value / num : Vector3d.Zero; } public void Normalize() { double num = Vector3d.Magnitude(this); if (num > 0.0) this = this / num; else this = Vector3d.Zero; } public static double Dot(Vector3d lhs, Vector3d rhs) => lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z; public static double Distance(Vector3d a, Vector3d b) { double num1 = a.x - b.x; double num2 = a.y - b.y; double num3 = a.z - b.z; return Math.Sqrt(num1 * num1 + num2 * num2 + num3 * num3); } public static Vector3d operator +(Vector3d a, Vector3d b) => new Vector3d(a.x + b.x, a.y + b.y, a.z + b.z); public static Vector3d operator -(Vector3d a, Vector3d b) => new Vector3d(a.x - b.x, a.y - b.y, a.z - b.z); public static Vector3d operator -(Vector3d a) => new Vector3d(-a.x, -a.y, -a.z); public static Vector3d operator *(Vector3d a, double d) => new Vector3d(a.x * d, a.y * d, a.z * d); public static Vector3d operator *(double d, Vector3d a) => new Vector3d(a.x * d, a.y * d, a.z * d); public static Vector3d operator /(Vector3d a, double d) => new Vector3d(a.x / d, a.y / d, a.z / d); public static bool operator ==(Vector3d lhs, Vector3d rhs) => lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z; public static bool operator !=(Vector3d lhs, Vector3d rhs) => !(lhs == rhs); public override string ToString() => this.ToString((string)null); public string ToString(string format) { if (string.IsNullOrEmpty(format)) format = "F2"; return "(" + this.x.ToString(format) + ", " + this.y.ToString(format) + ", " + this.z.ToString(format) + ")"; } } }