// ReSharper disable All // using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Windows; using WPFDark; using WPFDark.Internals; #nullable enable namespace WPFDark.Internals { [DebuggerDisplay("X:{X}, Y:{Y}")] public readonly struct ImmutableVec2_float : IEquatable { public readonly float X; public readonly float Y; public float Length => MathF.Sqrt(X * X + Y * Y); public float LengthSq => X * X + Y * Y; public static ImmutableVec2_float Zero = new ImmutableVec2_float(); public ImmutableVec2_float(float x, float y) => (X, Y) = (x, y); public ImmutableVec2_float(Point p) => (X, Y) = ((float)p.X, (float)p.Y); public ImmutableVec2_float(Size p) => (X, Y) = ((float)p.Width, (float)p.Height); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Point ToPoint() => new Point(X, Y); // ReSharper disable CompareOfFloatsByEqualityOperator [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(in ImmutableVec2_float source1, in ImmutableVec2_float source2) => source1.X == source2.X && source1.Y == source2.Y; // ReSharper restore CompareOfFloatsByEqualityOperator [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(in ImmutableVec2_float source1, in ImmutableVec2_float source2) => !(source1 == source2); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(ImmutableVec2_float other) => this == other; [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) { if (obj is ImmutableVec2_float other) return this == other; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() => HashCodeMaker.To32(HashCodeMaker.Make(X, Y)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(in ImmutableVec2_float other) { return MathF.Sqrt(DistanceSq(other)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSq(in ImmutableVec2_float other) { var dx = X - other.X; var dy = Y - other.Y; return dx * dx + dy * dy; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float SetSize(in ImmutableVec2_float v, float size) { var n = v.LengthSq; if (NumberHelper.AreCloseZero(n)) return new ImmutableVec2_float(0f, 0f); var l = 1f / MathF.Sqrt(n); return new ImmutableVec2_float(size * v.X * l, size * v.Y * l); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float Lerp(float ratio, in ImmutableVec2_float v1, in ImmutableVec2_float v2) => new ImmutableVec2_float( (v2.X - v1.X) * ratio + v1.X, (v2.Y - v1.Y) * ratio + v1.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float operator +(in ImmutableVec2_float v1, in ImmutableVec2_float v2) => new ImmutableVec2_float(v1.X + v2.X, v1.Y + v2.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float operator -(in ImmutableVec2_float v1, in ImmutableVec2_float v2) => new ImmutableVec2_float(v1.X - v2.X, v1.Y - v2.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float operator *(in ImmutableVec2_float v1, float v2) => new ImmutableVec2_float(v1.X * v2, v1.Y * v2); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_float operator /(in ImmutableVec2_float v1, float v2) => new ImmutableVec2_float(v1.X / v2, v1.Y / v2); public override string ToString() => $"({X},{Y})"; } [DebuggerDisplay("X:{X}, Y:{Y}")] public readonly struct ImmutableVec2_double : IEquatable { public readonly double X; public readonly double Y; public double Length => Math.Sqrt(X * X + Y * Y); public double LengthSq => X * X + Y * Y; public static ImmutableVec2_double Zero = new ImmutableVec2_double(); public ImmutableVec2_double(double x, double y) => (X, Y) = (x, y); public ImmutableVec2_double(Point p) => (X, Y) = ((double)p.X, (double)p.Y); public ImmutableVec2_double(Size p) => (X, Y) = ((double)p.Width, (double)p.Height); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Point ToPoint() => new Point(X, Y); // ReSharper disable CompareOfFloatsByEqualityOperator [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(in ImmutableVec2_double source1, in ImmutableVec2_double source2) => source1.X == source2.X && source1.Y == source2.Y; // ReSharper restore CompareOfFloatsByEqualityOperator [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(in ImmutableVec2_double source1, in ImmutableVec2_double source2) => !(source1 == source2); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(ImmutableVec2_double other) => this == other; [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) { if (obj is ImmutableVec2_double other) return this == other; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() => HashCodeMaker.To32(HashCodeMaker.Make(X, Y)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public double Distance(in ImmutableVec2_double other) { return Math.Sqrt(DistanceSq(other)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public double DistanceSq(in ImmutableVec2_double other) { var dx = X - other.X; var dy = Y - other.Y; return dx * dx + dy * dy; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double SetSize(in ImmutableVec2_double v, double size) { var n = v.LengthSq; if (NumberHelper.AreCloseZero(n)) return new ImmutableVec2_double(0d, 0d); var l = 1d / Math.Sqrt(n); return new ImmutableVec2_double(size * v.X * l, size * v.Y * l); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double Lerp(double ratio, in ImmutableVec2_double v1, in ImmutableVec2_double v2) => new ImmutableVec2_double( (v2.X - v1.X) * ratio + v1.X, (v2.Y - v1.Y) * ratio + v1.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double operator +(in ImmutableVec2_double v1, in ImmutableVec2_double v2) => new ImmutableVec2_double(v1.X + v2.X, v1.Y + v2.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double operator -(in ImmutableVec2_double v1, in ImmutableVec2_double v2) => new ImmutableVec2_double(v1.X - v2.X, v1.Y - v2.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double operator *(in ImmutableVec2_double v1, double v2) => new ImmutableVec2_double(v1.X * v2, v1.Y * v2); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ImmutableVec2_double operator /(in ImmutableVec2_double v1, double v2) => new ImmutableVec2_double(v1.X / v2, v1.Y / v2); public override string ToString() => $"({X},{Y})"; } }