using System; using System.Globalization; using Avalonia.Animation.Animators; namespace Avalonia { /// /// Defines a vector. /// public readonly struct PixelVector { /// /// The X vector. /// private readonly int _x; /// /// The Y vector. /// private readonly int _y; /// /// Initializes a new instance of the structure. /// /// The X vector. /// The Y vector. public PixelVector(int x, int y) { _x = x; _y = y; } /// /// Gets the X vector. /// public int X => _x; /// /// Gets the Y vector. /// public int Y => _y; /// /// Converts the to a . /// /// The vector. public static explicit operator PixelPoint(PixelVector a) { return new PixelPoint(a._x, a._y); } /// /// Calculates the dot product of two vectors /// /// First vector /// Second vector /// The dot product public static int operator *(PixelVector a, PixelVector b) { return a.X * b.X + a.Y * b.Y; } /// /// Scales a vector. /// /// The vector /// The scaling factor. /// The scaled vector. public static PixelVector operator *(PixelVector vector, int scale) { return new PixelVector(vector._x * scale, vector._y * scale); } /// /// Scales a vector. /// /// The vector /// The divisor. /// The scaled vector. public static PixelVector operator /(PixelVector vector, int scale) { return new PixelVector(vector._x / scale, vector._y / scale); } /// /// Length of the vector /// public double Length => Math.Sqrt(X * X + Y * Y); /// /// Negates a vector. /// /// The vector. /// The negated vector. public static PixelVector operator -(PixelVector a) { return new PixelVector(-a._x, -a._y); } /// /// Adds two vectors. /// /// The first vector. /// The second vector. /// A vector that is the result of the addition. public static PixelVector operator +(PixelVector a, PixelVector b) { return new PixelVector(a._x + b._x, a._y + b._y); } /// /// Subtracts two vectors. /// /// The first vector. /// The second vector. /// A vector that is the result of the subtraction. public static PixelVector operator -(PixelVector a, PixelVector b) { return new PixelVector(a._x - b._x, a._y - b._y); } /// /// Check if two vectors are equal (bitwise). /// /// /// public bool Equals(PixelVector other) { return _x == other._x && _y == other._y; } /// /// Check if two vectors are nearly equal (numerically). /// /// The other vector. /// True if vectors are nearly equal. public bool NearlyEquals(PixelVector other) { const float tolerance = float.Epsilon; return Math.Abs(_x - other._x) < tolerance && Math.Abs(_y - other._y) < tolerance; } public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; return obj is PixelVector vector && Equals(vector); } public override int GetHashCode() { unchecked { return (_x.GetHashCode() * 397) ^ _y.GetHashCode(); } } public static bool operator ==(PixelVector left, PixelVector right) { return left.Equals(right); } public static bool operator !=(PixelVector left, PixelVector right) { return !left.Equals(right); } /// /// Returns the string representation of the point. /// /// The string representation of the point. public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", _x, _y); } /// /// Returns a new vector with the specified X coordinate. /// /// The X coordinate. /// The new vector. public PixelVector WithX(int x) { return new PixelVector(x, _y); } /// /// Returns a new vector with the specified Y coordinate. /// /// The Y coordinate. /// The new vector. public PixelVector WithY(int y) { return new PixelVector(_x, y); } } }