mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-03 07:36:35 +08:00
使用PointBase代替Point
This commit is contained in:
466
AIStudio.Wpf.DiagramDesigner/Geometry/PointBase.cs
Normal file
466
AIStudio.Wpf.DiagramDesigner/Geometry/PointBase.cs
Normal file
@@ -0,0 +1,466 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner.Geometry
|
||||
{
|
||||
[Serializable]
|
||||
public struct PointBase : IFormattable
|
||||
{
|
||||
public static PointBase Zero { get; } = new PointBase(0, 0);
|
||||
|
||||
public PointBase(double x, double y)
|
||||
{
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中间X
|
||||
/// </summary>
|
||||
internal double _x;
|
||||
public double X
|
||||
{
|
||||
get
|
||||
{
|
||||
return _x;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_x = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中间Y
|
||||
/// </summary>
|
||||
internal double _y;
|
||||
public double Y
|
||||
{
|
||||
get
|
||||
{
|
||||
return _y;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_y = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double Dot(PointBase other) => X * other.X + Y * other.Y;
|
||||
|
||||
public PointBase Lerp(PointBase other, double t)
|
||||
=> new PointBase(X * (1.0 - t) + other.X * t, Y * (1.0 - t) + other.Y * t);
|
||||
|
||||
// Maybe just make Points mutable?
|
||||
public PointBase Add(double value) => new PointBase(X + value, Y + value);
|
||||
public PointBase Add(double x, double y) => new PointBase(X + x, Y + y);
|
||||
|
||||
public PointBase Substract(double value) => new PointBase(X - value, Y - value);
|
||||
public PointBase Substract(double x, double y) => new PointBase(X - x, Y - y);
|
||||
|
||||
public double DistanceTo(PointBase other)
|
||||
=> Math.Sqrt(Math.Pow(X - other.X, 2) + Math.Pow(Y - other.Y, 2));
|
||||
|
||||
public void Deconstruct(out double x, out double y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
|
||||
//public static PointBase operator -(PointBase a, PointBase b)
|
||||
//{
|
||||
// return new PointBase(a.X - b.X, a.Y - b.Y);
|
||||
//}
|
||||
//public static PointBase operator +(PointBase a, PointBase b)
|
||||
//{
|
||||
// return new PointBase(a.X + b.X, a.Y + b.Y);
|
||||
//}
|
||||
|
||||
public static implicit operator PointBase(Point point)
|
||||
{
|
||||
return new PointBase(point.X, point.Y);
|
||||
}
|
||||
|
||||
public static implicit operator Point(PointBase pointInfoBase)
|
||||
{
|
||||
return new Point(pointInfoBase.X, pointInfoBase.Y);
|
||||
}
|
||||
|
||||
//public override string ToString() => $"PointBase(x={X}, y={Y})";
|
||||
|
||||
#region Statics
|
||||
|
||||
/// <summary>
|
||||
/// Empty - a static property which provides an Empty rectangle. X and Y are positive-infinity
|
||||
/// and Width and Height are negative infinity. This is the only situation where Width or
|
||||
/// Height can be negative.
|
||||
/// </summary>
|
||||
public static PointBase Empty
|
||||
{
|
||||
get
|
||||
{
|
||||
return s_empty;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Statics
|
||||
|
||||
#region Private Methods
|
||||
|
||||
static private PointBase CreateEmptyRect()
|
||||
{
|
||||
PointBase point = new PointBase();
|
||||
// We can't set these via the property setters because negatives widths
|
||||
// are rejected in those APIs.
|
||||
point._x = Double.PositiveInfinity;
|
||||
point._y = Double.PositiveInfinity;
|
||||
return point;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private readonly static PointBase s_empty = CreateEmptyRect();
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Methods
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Compares two PointBase instances for exact equality.
|
||||
/// Note that double values can acquire error when operated upon, such that
|
||||
/// an exact comparison between two values which are logically equal may fail.
|
||||
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - true if the two PointBase instances are exactly equal, false otherwise
|
||||
/// </returns>
|
||||
/// <param name='point1'>The first PointBase to compare</param>
|
||||
/// <param name='point2'>The second PointBase to compare</param>
|
||||
public static bool operator ==(PointBase point1, PointBase point2)
|
||||
{
|
||||
return point1.X == point2.X &&
|
||||
point1.Y == point2.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two PointBase instances for exact inequality.
|
||||
/// Note that double values can acquire error when operated upon, such that
|
||||
/// an exact comparison between two values which are logically equal may fail.
|
||||
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - true if the two PointBase instances are exactly unequal, false otherwise
|
||||
/// </returns>
|
||||
/// <param name='point1'>The first PointBase to compare</param>
|
||||
/// <param name='point2'>The second PointBase to compare</param>
|
||||
public static bool operator !=(PointBase point1, PointBase point2)
|
||||
{
|
||||
return !(point1 == point2);
|
||||
}
|
||||
/// <summary>
|
||||
/// Compares two PointBase instances for object equality. In this equality
|
||||
/// Double.NaN is equal to itself, unlike in numeric equality.
|
||||
/// Note that double values can acquire error when operated upon, such that
|
||||
/// an exact comparison between two values which
|
||||
/// are logically equal may fail.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - true if the two PointBase instances are exactly equal, false otherwise
|
||||
/// </returns>
|
||||
/// <param name='point1'>The first PointBase to compare</param>
|
||||
/// <param name='point2'>The second PointBase to compare</param>
|
||||
public static bool Equals(PointBase point1, PointBase point2)
|
||||
{
|
||||
return point1.X.Equals(point2.X) &&
|
||||
point1.Y.Equals(point2.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equals - compares this PointBase with the passed in object. In this equality
|
||||
/// Double.NaN is equal to itself, unlike in numeric equality.
|
||||
/// Note that double values can acquire error when operated upon, such that
|
||||
/// an exact comparison between two values which
|
||||
/// are logically equal may fail.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - true if the object is an instance of PointBase and if it's equal to "this".
|
||||
/// </returns>
|
||||
/// <param name='o'>The object to compare to "this"</param>
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
if ((null == o) || !(o is PointBase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PointBase value = (PointBase)o;
|
||||
return PointBase.Equals(this, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equals - compares this PointBase with the passed in object. In this equality
|
||||
/// Double.NaN is equal to itself, unlike in numeric equality.
|
||||
/// Note that double values can acquire error when operated upon, such that
|
||||
/// an exact comparison between two values which
|
||||
/// are logically equal may fail.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - true if "value" is equal to "this".
|
||||
/// </returns>
|
||||
/// <param name='value'>The PointBase to compare to "this"</param>
|
||||
public bool Equals(PointBase value)
|
||||
{
|
||||
return PointBase.Equals(this, value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the HashCode for this PointBase
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// int - the HashCode for this PointBase
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// Perform field-by-field XOR of HashCodes
|
||||
return X.GetHashCode() ^
|
||||
Y.GetHashCode();
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Parse - returns an instance converted from the provided string using
|
||||
///// the culture "en-US"
|
||||
///// <param name="source"> string with PointBase data </param>
|
||||
///// </summary>
|
||||
//public static PointBase Parse(string source)
|
||||
//{
|
||||
// IFormatProvider formatProvider = System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS;
|
||||
|
||||
// TokenizerHelper th = new TokenizerHelper(source, formatProvider);
|
||||
|
||||
// PointBase value;
|
||||
|
||||
// String firstToken = th.NextTokenRequired();
|
||||
|
||||
// value = new PointBase(
|
||||
// Convert.ToDouble(firstToken, formatProvider),
|
||||
// Convert.ToDouble(th.NextTokenRequired(), formatProvider));
|
||||
|
||||
// // There should be no more tokens in this string.
|
||||
// th.LastTokenRequired();
|
||||
|
||||
// return value;
|
||||
//}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Internal Properties
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string representation of this object based on the current culture.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string representation of this object.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
// Delegate to the internal method which implements all ToString calls.
|
||||
return ConvertToString(null /* format string */, null /* format provider */);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string representation of this object based on the IFormatProvider
|
||||
/// passed in. If the provider is null, the CurrentCulture is used.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string representation of this object.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
// Delegate to the internal method which implements all ToString calls.
|
||||
return ConvertToString(null /* format string */, provider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string representation of this object based on the format string
|
||||
/// and IFormatProvider passed in.
|
||||
/// If the provider is null, the CurrentCulture is used.
|
||||
/// See the documentation for IFormattable for more information.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string representation of this object.
|
||||
/// </returns>
|
||||
string IFormattable.ToString(string format, IFormatProvider provider)
|
||||
{
|
||||
// Delegate to the internal method which implements all ToString calls.
|
||||
return ConvertToString(format, provider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string representation of this object based on the format string
|
||||
/// and IFormatProvider passed in.
|
||||
/// If the provider is null, the CurrentCulture is used.
|
||||
/// See the documentation for IFormattable for more information.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string representation of this object.
|
||||
/// </returns>
|
||||
internal string ConvertToString(string format, IFormatProvider provider)
|
||||
{
|
||||
// Helper to get the numeric list separator for a given culture.
|
||||
char separator = ',';
|
||||
return String.Format(provider,
|
||||
"{1:" + format + "}{0}{2:" + format + "}",
|
||||
separator,
|
||||
_x,
|
||||
_y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion Internal Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Offset - update the location by adding offsetX to X and offsetY to Y
|
||||
/// </summary>
|
||||
/// <param name="offsetX"> The offset in the x dimension </param>
|
||||
/// <param name="offsetY"> The offset in the y dimension </param>
|
||||
public void Offset(double offsetX, double offsetY)
|
||||
{
|
||||
_x += offsetX;
|
||||
_y += offsetY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator PointBase + Vector
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// PointBase - The result of the addition
|
||||
/// </returns>
|
||||
/// <param name="point"> The PointBase to be added to the Vector </param>
|
||||
/// <param name="vector"> The Vectr to be added to the PointBase </param>
|
||||
public static PointBase operator +(PointBase point, VectorBase vector)
|
||||
{
|
||||
return new PointBase(point._x + vector._x, point._y + vector._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add: PointBase + Vector
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// PointBase - The result of the addition
|
||||
/// </returns>
|
||||
/// <param name="point"> The PointBase to be added to the Vector </param>
|
||||
/// <param name="vector"> The Vector to be added to the PointBase </param>
|
||||
public static PointBase Add(PointBase point, VectorBase vector)
|
||||
{
|
||||
return new PointBase(point._x + vector._x, point._y + vector._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator PointBase - Vector
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// PointBase - The result of the subtraction
|
||||
/// </returns>
|
||||
/// <param name="point"> The PointBase from which the Vector is subtracted </param>
|
||||
/// <param name="vector"> The Vector which is subtracted from the PointBase </param>
|
||||
public static PointBase operator -(PointBase point, VectorBase vector)
|
||||
{
|
||||
return new PointBase(point._x - vector._x, point._y - vector._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract: PointBase - Vector
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// PointBase - The result of the subtraction
|
||||
/// </returns>
|
||||
/// <param name="point"> The PointBase from which the Vector is subtracted </param>
|
||||
/// <param name="vector"> The Vector which is subtracted from the PointBase </param>
|
||||
public static PointBase Subtract(PointBase point, VectorBase vector)
|
||||
{
|
||||
return new PointBase(point._x - vector._x, point._y - vector._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator PointBase - PointBase
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Vector - The result of the subtraction
|
||||
/// </returns>
|
||||
/// <param name="point1"> The PointBase from which point2 is subtracted </param>
|
||||
/// <param name="point2"> The PointBase subtracted from point1 </param>
|
||||
public static VectorBase operator -(PointBase point1, PointBase point2)
|
||||
{
|
||||
return new VectorBase(point1._x - point2._x, point1._y - point2._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtract: PointBase - PointBase
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Vector - The result of the subtraction
|
||||
/// </returns>
|
||||
/// <param name="point1"> The PointBase from which point2 is subtracted </param>
|
||||
/// <param name="point2"> The PointBase subtracted from point1 </param>
|
||||
public static VectorBase Subtract(PointBase point1, PointBase point2)
|
||||
{
|
||||
return new VectorBase(point1._x - point2._x, point1._y - point2._y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator PointBase * Matrix
|
||||
/// </summary>
|
||||
//public static PointBase operator *(PointBase point, Matrix matrix)
|
||||
//{
|
||||
// return matrix.Transform(point);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply: PointBase * Matrix
|
||||
/// </summary>
|
||||
//public static PointBase Multiply(PointBase point, Matrix matrix)
|
||||
//{
|
||||
// return matrix.Transform(point);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Explicit conversion to Size. Note that since Size cannot contain negative values,
|
||||
/// the resulting size will contains the absolute values of X and Y
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Size - A Size equal to this PointBase
|
||||
/// </returns>
|
||||
/// <param name="point"> PointBase - the PointBase to convert to a Size </param>
|
||||
public static explicit operator SizeBase(PointBase point)
|
||||
{
|
||||
return new SizeBase(Math.Abs(point._x), Math.Abs(point._y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Explicit conversion to Vector
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Vector - A Vector equal to this PointBase
|
||||
/// </returns>
|
||||
/// <param name="point"> PointBase - the PointBase to convert to a Vector </param>
|
||||
public static explicit operator VectorBase(PointBase point)
|
||||
{
|
||||
return new VectorBase(point._x, point._y);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user