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);
+ }
+ }
+}