From 36114f798158c57564145bd69c504a28226ef320 Mon Sep 17 00:00:00 2001
From: SeWZC <36623158+SeWZC@users.noreply.github.com>
Date: Tue, 22 Oct 2024 15:39:31 +0800
Subject: [PATCH] =?UTF-8?q?BoundingBox2d=20=E4=B8=AD=E5=88=A0=E9=99=A4?=
=?UTF-8?q?=E4=B8=8E=E5=B7=A6=E5=8F=B3=E3=80=81=E4=B8=8A=E4=B8=8B=E6=9C=89?=
=?UTF-8?q?=E5=85=B3=E7=9A=84=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E4=B8=BA=E4=BB=A5=E4=B8=AD=E5=BF=83=E7=82=B9=E4=BB=A5=E5=8F=8A?=
=?UTF-8?q?=E5=A4=A7=E5=B0=8F=E4=B8=BA=E5=9F=BA=E7=A1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BoundingBox2D.cs | 115 ++++++++++++------
DotNetCampus.Numerics.Geometry/Size2D.cs | 29 ++++-
2 files changed, 106 insertions(+), 38 deletions(-)
diff --git a/DotNetCampus.Numerics.Geometry/BoundingBox2D.cs b/DotNetCampus.Numerics.Geometry/BoundingBox2D.cs
index c204b34..d49e101 100644
--- a/DotNetCampus.Numerics.Geometry/BoundingBox2D.cs
+++ b/DotNetCampus.Numerics.Geometry/BoundingBox2D.cs
@@ -16,6 +16,13 @@ public readonly record struct BoundingBox2D
#region 静态方法
+ private static BoundingBox2D CreateInternal(double minX, double minY, double maxX, double maxY)
+ {
+ return new BoundingBox2D(
+ new Point2D((minX + maxX) / 2, (minY + maxY) / 2),
+ new Size2D((maxX - minX) / 2, (maxY - minY) / 2));
+ }
+
///
/// 创建一个 2 维边界框。
///
@@ -31,18 +38,40 @@ public static BoundingBox2D Create(double minX, double minY, double maxX, double
throw new ArgumentException("The minimum value of the bounding box must be less than or equal to the maximum value.");
}
- return new BoundingBox2D(minX, minY, maxX, maxY);
+ return CreateInternal(minX, minY, maxX, maxY);
}
///
- /// 通过左上角位置和大小创建 2 维边界框。
+ /// 通过最小坐标位置和大小创建 2 维边界框。
///
- /// 左上角位置。
+ /// 最小坐标位置。
/// 大小。
/// 创建的 2 维边界框。
- public static BoundingBox2D CreateByLocationSize(Point2D location, Size2D size)
+ public static BoundingBox2D CreateByMinPointSize(Point2D minPoint, Size2D size)
{
- return Create(location.X, location.Y, location.X + size.Width, location.Y + size.Height);
+ if (size.Width < 0 || size.Height < 0)
+ {
+ throw new ArgumentException("The size of the bounding box cannot be negative.");
+ }
+
+ var halfSize = size / 2;
+ return new BoundingBox2D(minPoint + new Vector2D(halfSize.Width, halfSize.Height), halfSize);
+ }
+
+ ///
+ /// 通过中心点和大小创建 2 维边界框。
+ ///
+ ///
+ ///
+ ///
+ public static BoundingBox2D CreateByCenterSize(Point2D center, Size2D size)
+ {
+ if (size.Width < 0 || size.Height < 0)
+ {
+ throw new ArgumentException("The size of the bounding box cannot be negative.");
+ }
+
+ return new BoundingBox2D(center, size / 2);
}
///
@@ -52,7 +81,7 @@ public static BoundingBox2D CreateByLocationSize(Point2D location, Size2D size)
/// 宽高为 0 但不为空的 2 维边界框。
public static BoundingBox2D Create(Point2D point)
{
- return new BoundingBox2D(point.X, point.Y, point.X, point.Y);
+ return new BoundingBox2D(point, new Size2D());
}
///
@@ -63,7 +92,7 @@ public static BoundingBox2D Create(Point2D point)
/// 包含两个点的最小 2 维边界框。
public static BoundingBox2D Create(Point2D point1, Point2D point2)
{
- return new BoundingBox2D(
+ return CreateInternal(
Math.Min(point1.X, point2.X),
Math.Min(point1.Y, point2.Y),
Math.Max(point1.X, point2.X),
@@ -95,7 +124,7 @@ public static BoundingBox2D Create(IReadOnlyCollection points)
maxY = Math.Max(maxY, point.Y);
}
- return new BoundingBox2D(minX, minY, maxX, maxY);
+ return CreateInternal(minX, minY, maxX, maxY);
}
///
@@ -113,7 +142,7 @@ public static BoundingBox2D TryCreate(double minX, double minY, double maxX, dou
return Empty;
}
- return new BoundingBox2D(minX, minY, maxX, maxY);
+ return CreateInternal(minX, minY, maxX, maxY);
}
#endregion
@@ -130,39 +159,64 @@ public static BoundingBox2D TryCreate(double minX, double minY, double maxX, dou
#region 属性
///
- /// 最小 X 值。
+ /// 中心点。
///
- public double MinX { get; }
+ public Point2D Center { get; }
///
- /// 最小 Y 值。
+ /// 边界框的大小的一半。
///
- public double MinY { get; }
+ public Size2D HalfSize { get; }
///
- /// 最大 X 值。
+ /// 半宽度。
///
- public double MaxX { get; }
+ public double HalfWidth => HalfSize.Width;
///
- /// 最大 Y 值。
+ /// 半高度。
///
- public double MaxY { get; }
+ public double HalfHeight => HalfSize.Height;
///
- /// 边界框是否为空。宽高为 0 的边界框不一定为空。
+ /// 边界框的大小。
///
- public bool IsEmpty => !_isNotEmpty;
+ public Size2D Size => new(Width, Height);
///
/// 宽度。
///
- public double Width => MaxX - MinX;
+ public double Width => HalfWidth * 2;
///
/// 高度。
///
- public double Height => MaxY - MinY;
+ public double Height => HalfHeight * 2;
+
+ ///
+ /// 最小 X 值。
+ ///
+ public double MinX => Math.Min(Center.X - HalfWidth, Center.X + HalfWidth);
+
+ ///
+ /// 最小 Y 值。
+ ///
+ public double MinY => Math.Min(Center.Y - HalfHeight, Center.Y + HalfHeight);
+
+ ///
+ /// 最大 X 值。
+ ///
+ public double MaxX => Math.Max(Center.X - HalfWidth, Center.X + HalfWidth);
+
+ ///
+ /// 最大 Y 值。
+ ///
+ public double MaxY => Math.Max(Center.Y - HalfHeight, Center.Y + HalfHeight);
+
+ ///
+ /// 边界框是否为空。宽高为 0 的边界框不一定为空。
+ ///
+ public bool IsEmpty => !_isNotEmpty;
///
/// 边界框坐标值最小的点(MinX, MinY)。
@@ -174,11 +228,6 @@ public static BoundingBox2D TryCreate(double minX, double minY, double maxX, dou
///
public Point2D MaxPoint => new(MaxX, MaxY);
- ///
- /// 中心点。
- ///
- public Point2D Center => new((MinX + MaxX) / 2, (MinY + MaxY) / 2);
-
#endregion
#region 构造函数
@@ -188,21 +237,13 @@ public static BoundingBox2D TryCreate(double minX, double minY, double maxX, dou
///
public BoundingBox2D()
{
- MinX = 0;
- MinY = 0;
- MaxX = 0;
- MaxY = 0;
-
_isNotEmpty = false;
}
- private BoundingBox2D(double minX, double minY, double maxX, double maxY)
+ private BoundingBox2D(Point2D center, Size2D halfSize)
{
- MinX = minX;
- MinY = minY;
- MaxX = maxX;
- MaxY = maxY;
-
+ Center = center;
+ HalfSize = halfSize;
_isNotEmpty = true;
}
diff --git a/DotNetCampus.Numerics.Geometry/Size2D.cs b/DotNetCampus.Numerics.Geometry/Size2D.cs
index 5f37a8c..a0837a4 100644
--- a/DotNetCampus.Numerics.Geometry/Size2D.cs
+++ b/DotNetCampus.Numerics.Geometry/Size2D.cs
@@ -5,4 +5,31 @@ namespace DotNetCampus.Numerics.Geometry;
///
/// 宽度。
/// 高度。
-public readonly record struct Size2D(double Width, double Height);
+public readonly record struct Size2D(double Width, double Height)
+{
+ #region 运算符重载
+
+ ///
+ /// 将大小按指定倍数进行缩放。
+ ///
+ ///
+ /// 缩放倍数。大于 1 为放大,小于 1 为缩小。
+ ///
+ public static Size2D operator *(Size2D size, double scalar)
+ {
+ return new Size2D(size.Width * scalar, size.Height * scalar);
+ }
+
+ ///
+ /// 将大小按指定倍数进行反向缩放。
+ ///
+ ///
+ /// 反向缩放倍数。大于 1 为缩小,小于 1 为放大。
+ ///
+ public static Size2D operator /(Size2D size, double scalar)
+ {
+ return new Size2D(size.Width / scalar, size.Height / scalar);
+ }
+
+ #endregion
+}