From 3e786dbadb4df265eb958dba8be06f7e48ad0664 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 27 Jul 2019 11:04:04 +0300 Subject: [PATCH] PixelVector and stuff --- src/Avalonia.Visuals/Media/PixelPoint.cs | 55 ++++++ src/Avalonia.Visuals/Media/PixelRect.cs | 11 ++ src/Avalonia.Visuals/Media/PixelVector.cs | 205 ++++++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 src/Avalonia.Visuals/Media/PixelVector.cs diff --git a/src/Avalonia.Visuals/Media/PixelPoint.cs b/src/Avalonia.Visuals/Media/PixelPoint.cs index 995781ee9f..1fc102045e 100644 --- a/src/Avalonia.Visuals/Media/PixelPoint.cs +++ b/src/Avalonia.Visuals/Media/PixelPoint.cs @@ -59,6 +59,59 @@ namespace Avalonia { return !(left == right); } + + /// + /// Converts the to a . + /// + /// The point. + public static implicit operator PixelVector(PixelPoint p) + { + return new PixelVector(p.X, p.Y); + } + + /// + /// Adds two points. + /// + /// The first point. + /// The second point. + /// A point that is the result of the addition. + public static PixelPoint operator +(PixelPoint a, PixelPoint b) + { + return new PixelPoint(a.X + b.X, a.Y + b.Y); + } + + /// + /// Adds a vector to a point. + /// + /// The point. + /// The vector. + /// A point that is the result of the addition. + public static PixelPoint operator +(PixelPoint a, PixelVector b) + { + return new PixelPoint(a.X + b.X, a.Y + b.Y); + } + + /// + /// Subtracts two points. + /// + /// The first point. + /// The second point. + /// A point that is the result of the subtraction. + public static PixelPoint operator -(PixelPoint a, PixelPoint b) + { + return new PixelPoint(a.X - b.X, a.Y - b.Y); + } + + /// + /// Subtracts a vector from a point. + /// + /// The point. + /// The vector. + /// A point that is the result of the subtraction. + public static PixelPoint operator -(PixelPoint a, PixelVector b) + { + return new PixelPoint(a.X - b.X, a.Y - b.Y); + } /// /// Parses a string. @@ -106,6 +159,8 @@ namespace Avalonia return hash; } } + + /// /// Returns a new with the same Y co-ordinate and the specified X co-ordinate. diff --git a/src/Avalonia.Visuals/Media/PixelRect.cs b/src/Avalonia.Visuals/Media/PixelRect.cs index 9c8e5ad1c4..75987681ff 100644 --- a/src/Avalonia.Visuals/Media/PixelRect.cs +++ b/src/Avalonia.Visuals/Media/PixelRect.cs @@ -261,6 +261,17 @@ namespace Avalonia { return (rect.X < Right) && (X < rect.Right) && (rect.Y < Bottom) && (Y < rect.Bottom); } + + /// + /// Translates the rectangle by an offset. + /// + /// The offset. + /// The translated rectangle. + public PixelRect Translate(PixelVector offset) + { + return new PixelRect(Position + offset, Size); + } + /// /// Gets the union of two rectangles. diff --git a/src/Avalonia.Visuals/Media/PixelVector.cs b/src/Avalonia.Visuals/Media/PixelVector.cs new file mode 100644 index 0000000000..b959b462c2 --- /dev/null +++ b/src/Avalonia.Visuals/Media/PixelVector.cs @@ -0,0 +1,205 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Globalization; +using Avalonia.Animation.Animators; +using JetBrains.Annotations; + +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) + { + // ReSharper disable CompareOfFloatsByEqualityOperator + return _x == other._x && _y == other._y; + // ReSharper restore CompareOfFloatsByEqualityOperator + } + + /// + /// Check if two vectors are nearly equal (numerically). + /// + /// The other vector. + /// True if vectors are nearly equal. + [Pure] + 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); + } + } +}