From dd0ba84cbe25cdb719a3e853572347a4d0269658 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=80=90=E7=A8=8B=E5=BA=8F=E3=80=91=E7=A8=8B=E4=B8=80?=
=?UTF-8?q?=E5=B3=B0?= <649669121@qq.com>
Date: Thu, 10 Nov 2022 15:15:57 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B03d=E7=9B=B4=E7=BA=BF=E4=B8=8E?=
=?UTF-8?q?Box3d=E7=9A=84=E7=9B=B8=E4=BA=A4=E6=A3=80=E6=B5=8B=EF=BC=8C?=
=?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Intersection/IntrLine2dBox2d.cs | 13 +---
Intersection/IntrLine3dBox3d.cs | 119 +++++++++++++++++++++++++++++++-
Math/Box3d.cs | 9 +++
Math/Line2d.cs | 9 ++-
4 files changed, 134 insertions(+), 16 deletions(-)
diff --git a/Intersection/IntrLine2dBox2d.cs b/Intersection/IntrLine2dBox2d.cs
index 3205461..2d1ea37 100644
--- a/Intersection/IntrLine2dBox2d.cs
+++ b/Intersection/IntrLine2dBox2d.cs
@@ -25,22 +25,15 @@ namespace Oroxylum
public IntrLine2dBox2d(Line2d line, Box2d box)
{
- LineParam0 = 0;
- LineParam1 = 0;
+ LineParam0 = -float.MaxValue;
+ LineParam1 = float.MaxValue;
Point0 = 0;
Point1 = 0;
Result = E_IntersectionResult.NotComputed;
Type = E_IntersectionType.Empty;
Quantity = 0;
- float2 direction = line.Direction;
-
- if (!direction.IsNormalized())
- direction = math.normalize(direction);
-
- LineParam0 = -float.MaxValue;
- LineParam1 = float.MaxValue;
- DoClipping(ref LineParam0, ref LineParam1, line.Origin, direction, box,
+ DoClipping(ref LineParam0, ref LineParam1, line.Origin, line.Direction, box,
true, ref Quantity, ref Point0, ref Point1, ref Type);
Result = (Type != E_IntersectionType.Empty) ?
diff --git a/Intersection/IntrLine3dBox3d.cs b/Intersection/IntrLine3dBox3d.cs
index 8d2fc70..775c7ca 100644
--- a/Intersection/IntrLine3dBox3d.cs
+++ b/Intersection/IntrLine3dBox3d.cs
@@ -8,14 +8,127 @@
*/
+using Unity.Mathematics;
+
namespace Oroxylum
{
///
/// 相交计算结果:3d直线与3dBox
///
- public class IntrLine3dBox3d
+ public struct IntrLine3dBox3d
{
+ public int Quantity;
+ public E_IntersectionResult Result;
+ public E_IntersectionType Type;
+ public float LineParam0, LineParam1;
+ public float3 Point0;
+ public float3 Point1;
+
+ public IntrLine3dBox3d(Line3d line, Box3d box)
+ {
+ Result = E_IntersectionResult.NotComputed;
+ Type = E_IntersectionType.Empty;
+ LineParam0 = -float.MaxValue;
+ LineParam1 = float.MaxValue;
+ Point0 = 0;
+ Point1 = 1;
+ Quantity = 0;
+
+ DoClipping(ref LineParam0, ref LineParam1, line.Origin, line.Direction, box,
+ true, ref Quantity, ref Point0, ref Point1, ref Type);
+
+ Result = (Type != E_IntersectionType.Empty) ?
+ E_IntersectionResult.Intersects : E_IntersectionResult.NoIntersection;
+ }
+
+ public static bool DoClipping(ref float t0, ref float t1,
+ float3 origin, float3 direction,
+ Box3d box, bool solid, ref int quantity,
+ ref float3 point0, ref float3 point1,
+ ref E_IntersectionType intrType)
+ {
+ // Convert linear component to box coordinates.
+ float3 diff = origin - box.Center;
+ float3 BOrigin = new float3(
+ diff.Dot(box.AxisX),
+ diff.Dot(box.AxisY),
+ diff.Dot(box.AxisZ)
+ );
+ float3 BDirection = new float3(
+ direction.Dot(box.AxisX),
+ direction.Dot(box.AxisY),
+ direction.Dot(box.AxisZ)
+ );
+
+ double saveT0 = t0, saveT1 = t1;
+ bool notAllClipped =
+ Clip(+BDirection.x, -BOrigin.x - box.Extent.x, ref t0, ref t1) &&
+ Clip(-BDirection.x, +BOrigin.x - box.Extent.x, ref t0, ref t1) &&
+ Clip(+BDirection.y, -BOrigin.y - box.Extent.y, ref t0, ref t1) &&
+ Clip(-BDirection.y, +BOrigin.y - box.Extent.y, ref t0, ref t1) &&
+ Clip(+BDirection.z, -BOrigin.z - box.Extent.z, ref t0, ref t1) &&
+ Clip(-BDirection.z, +BOrigin.z - box.Extent.z, ref t0, ref t1);
+
+ if (notAllClipped && (solid || t0 != saveT0 || t1 != saveT1))
+ {
+ if (t1 > t0)
+ {
+ intrType = E_IntersectionType.LineSegment;
+ quantity = 2;
+ point0 = origin + t0 * direction;
+ point1 = origin + t1 * direction;
+ }
+ else
+ {
+ intrType = E_IntersectionType.Point;
+ quantity = 1;
+ point0 = origin + t0 * direction;
+ }
+ }
+ else
+ {
+ quantity = 0;
+ intrType = E_IntersectionType.Empty;
+ }
+
+ return intrType != E_IntersectionType.Empty;
+ }
+
+ private static bool Clip(float denom, float numer, ref float t0, ref float t1)
+ {
+ // Return value is 'true' if line segment intersects the current test
+ // plane. Otherwise 'false' is returned in which case the line segment
+ // is entirely clipped.
+
+ if (denom > 0)
+ {
+ if (numer - denom * t1 > OMath.ZeroTolerance)
+ {
+ return false;
+ }
+ if (numer > denom * t0)
+ {
+ t0 = numer / denom;
+ }
+ return true;
+ }
+ else if (denom < 0)
+ {
+ if (numer - denom * t0 > OMath.ZeroTolerance)
+ {
+ return false;
+ }
+ if (numer > denom * t1)
+ {
+ t1 = numer / denom;
+ }
+ return true;
+ }
+ else
+ {
+ return numer <= 0;
+ }
+ }
-
}
-}
+}
\ No newline at end of file
diff --git a/Math/Box3d.cs b/Math/Box3d.cs
index 45c3099..76e5f0f 100644
--- a/Math/Box3d.cs
+++ b/Math/Box3d.cs
@@ -8,6 +8,8 @@
*/
+using Unity.Mathematics;
+
namespace Oroxylum
{
///
@@ -15,6 +17,13 @@ namespace Oroxylum
///
public struct Box3d
{
+ public float3 Center;
+ public float3 Extent;
+
+ public float3 AxisX => new float3(1.0f, 0.0f, 0.0f);
+ public float3 AxisY => new float3(0.0f, 1.0f, 0.0f);
+ public float3 AxisZ => new float3(0.0f, 0.0f, 1.0f);
+
}
diff --git a/Math/Line2d.cs b/Math/Line2d.cs
index 3781f88..c64a16f 100644
--- a/Math/Line2d.cs
+++ b/Math/Line2d.cs
@@ -18,13 +18,16 @@ namespace Oroxylum
public struct Line2d
{
public float2 Origin;
- public float2 Direction;
+ ///
+ /// 直线方向,已经 normalize
+ ///
+ public float2 Direction;
public Line2d(float2 origin, float2 direction)
{
this.Origin = origin;
- this.Direction = direction;
+ this.Direction = math.normalize(direction);
}
public static Line2d FromPoints(float2 p0, float2 p1)
@@ -37,7 +40,7 @@ namespace Oroxylum
public float2 ClosestPoint(float2 p)
{
float t = (p - Origin).Dot(Direction);
- return Origin + t * Direction;
+ return Origin + (t * Direction);
}
public double DistanceSquared(float2 p)
--
GitLab