@@ -7,6 +7,24 @@ namespace FixedMathSharp.Tests.Bounds;
77
88public class BoundingBoxTests
99{
10+ private readonly struct UnsupportedBound : IBound
11+ {
12+ public Vector3d Min { get ; }
13+ public Vector3d Max { get ; }
14+
15+ public UnsupportedBound ( Vector3d min , Vector3d max )
16+ {
17+ Min = min ;
18+ Max = max ;
19+ }
20+
21+ public bool Contains ( Vector3d point ) => false ;
22+
23+ public bool Intersects ( IBound other ) => false ;
24+
25+ public Vector3d ProjectPoint ( Vector3d point ) => point ;
26+ }
27+
1028 #region Test: Constructor and Property
1129
1230 [ Fact ]
@@ -127,6 +145,14 @@ public void DistanceToSurface_WorksCorrectly()
127145 Assert . Equal ( Fixed64 . One , box . DistanceToSurface ( point ) ) ;
128146 }
129147
148+ [ Fact ]
149+ public void DistanceToSurface_InsidePoint_ReturnsZero ( )
150+ {
151+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
152+
153+ Assert . Equal ( Fixed64 . Zero , box . DistanceToSurface ( new Vector3d ( 1 , 1 , 1 ) ) ) ;
154+ }
155+
130156 [ Fact ]
131157 public void ClosestPointOnSurface_ReturnsCorrectPoint ( )
132158 {
@@ -137,6 +163,36 @@ public void ClosestPointOnSurface_ReturnsCorrectPoint()
137163 Assert . Equal ( new Vector3d ( 2 , 2 , 2 ) , closestPoint ) ;
138164 }
139165
166+ [ Fact ]
167+ public void ClosestPointOnSurface_InsidePoint_UsesNearestFace ( )
168+ {
169+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
170+
171+ Assert . Equal ( new Vector3d ( - 2 , 0.5 , 0.25 ) , box . ClosestPointOnSurface ( new Vector3d ( - 1.75 , 0.5 , 0.25 ) ) ) ;
172+ Assert . Equal ( new Vector3d ( 0.25 , 2 , - 0.75 ) , box . ClosestPointOnSurface ( new Vector3d ( 0.25 , 1.9 , - 0.75 ) ) ) ;
173+ Assert . Equal ( new Vector3d ( - 0.25 , 0.5 , - 2 ) , box . ClosestPointOnSurface ( new Vector3d ( - 0.25 , 0.5 , - 1.8 ) ) ) ;
174+ }
175+
176+ [ Fact ]
177+ public void ProjectPoint_ClampsToBounds ( )
178+ {
179+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
180+
181+ var projected = box . ProjectPoint ( new Vector3d ( 5 , - 3 , 1 ) ) ;
182+
183+ Assert . Equal ( new Vector3d ( 2 , - 2 , 1 ) , projected ) ;
184+ }
185+
186+ [ Fact ]
187+ public void GetPointOnSurfaceTowardsObject_UsesProjectedPoint ( )
188+ {
189+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
190+
191+ var point = box . GetPointOnSurfaceTowardsObject ( new Vector3d ( 5 , 1 , 0 ) ) ;
192+
193+ Assert . Equal ( new Vector3d ( 2 , 1 , 0 ) , point ) ;
194+ }
195+
140196 #endregion
141197
142198 #region Test: Equality
@@ -179,6 +235,23 @@ public void SetBoundingBox_KeepsSizeAndScopeInSync()
179235 Assert . Equal ( newScope * Fixed64 . Two , box . Proportions ) ;
180236 }
181237
238+ [ Fact ]
239+ public void Inequality_DifferentBox_ReturnsTrue ( )
240+ {
241+ var box1 = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
242+ var box2 = new BoundingBox ( new Vector3d ( 1 , 1 , 1 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
243+
244+ Assert . True ( box1 != box2 ) ;
245+ }
246+
247+ [ Fact ]
248+ public void Equals_WithDifferentObjectType_ReturnsFalse ( )
249+ {
250+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
251+
252+ Assert . False ( box . Equals ( "not-a-box" ) ) ;
253+ }
254+
182255 #endregion
183256
184257 #region Test: Edge Cases
@@ -226,6 +299,55 @@ public void SetMinMax_SetsCorrectCenterAndSize()
226299 Assert . Equal ( new Vector3d ( 4 , 4 , 4 ) , box . Proportions ) ;
227300 }
228301
302+ [ Fact ]
303+ public void Center_Setter_RepositionsBoundsWithoutChangingSize ( )
304+ {
305+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 6 , 8 ) ) ;
306+
307+ box . Center = new Vector3d ( 5 , - 1 , 3 ) ;
308+
309+ Assert . Equal ( new Vector3d ( 5 , - 1 , 3 ) , box . Center ) ;
310+ Assert . Equal ( new Vector3d ( 4 , 6 , 8 ) , box . Proportions ) ;
311+ Assert . Equal ( new Vector3d ( 3 , - 4 , - 1 ) , box . Min ) ;
312+ Assert . Equal ( new Vector3d ( 7 , 2 , 7 ) , box . Max ) ;
313+ }
314+
315+ [ Fact ]
316+ public void Proportions_Setter_ResizesBoundsWithoutChangingCenter ( )
317+ {
318+ var box = new BoundingBox ( new Vector3d ( 1 , 2 , 3 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
319+
320+ box . Proportions = new Vector3d ( 6 , 8 , 10 ) ;
321+
322+ Assert . Equal ( new Vector3d ( 1 , 2 , 3 ) , box . Center ) ;
323+ Assert . Equal ( new Vector3d ( - 2 , - 2 , - 2 ) , box . Min ) ;
324+ Assert . Equal ( new Vector3d ( 4 , 6 , 8 ) , box . Max ) ;
325+ }
326+
327+ [ Fact ]
328+ public void Orient_WithNullSize_PreservesCurrentProportions ( )
329+ {
330+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 6 , 8 ) ) ;
331+
332+ box . Orient ( new Vector3d ( 10 , 20 , 30 ) , null ) ;
333+
334+ Assert . Equal ( new Vector3d ( 10 , 20 , 30 ) , box . Center ) ;
335+ Assert . Equal ( new Vector3d ( 4 , 6 , 8 ) , box . Proportions ) ;
336+ }
337+
338+ [ Fact ]
339+ public void Orient_WithExplicitSize_UsesProvidedDimensions ( )
340+ {
341+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
342+
343+ box . Orient ( new Vector3d ( 1 , 2 , 3 ) , new Vector3d ( 2 , 4 , 6 ) ) ;
344+
345+ Assert . Equal ( new Vector3d ( 1 , 2 , 3 ) , box . Center ) ;
346+ Assert . Equal ( new Vector3d ( 2 , 4 , 6 ) , box . Proportions ) ;
347+ Assert . Equal ( new Vector3d ( 0 , 0 , 0 ) , box . Min ) ;
348+ Assert . Equal ( new Vector3d ( 2 , 4 , 6 ) , box . Max ) ;
349+ }
350+
229351 #endregion
230352
231353 #region Test: Vertex Cache Safety
@@ -242,6 +364,38 @@ public void Vertices_UpdateAfterMutation()
242364 Assert . NotEqual ( original , updated ) ;
243365 }
244366
367+ [ Fact ]
368+ public void Union_EnclosesBothBoxes ( )
369+ {
370+ var a = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 2 , 2 , 2 ) ) ;
371+ var b = new BoundingBox ( new Vector3d ( 4 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
372+
373+ var union = BoundingBox . Union ( a , b ) ;
374+
375+ Assert . Equal ( new Vector3d ( - 1 , - 2 , - 2 ) , union . Min ) ;
376+ Assert . Equal ( new Vector3d ( 6 , 2 , 2 ) , union . Max ) ;
377+ }
378+
379+ [ Fact ]
380+ public void FindClosestPointsBetweenBoxes_ReturnsClosestPointOnFirstBoxSurface ( )
381+ {
382+ var a = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 2 , 2 , 2 ) ) ;
383+ var b = new BoundingBox ( new Vector3d ( 5 , 0 , 0 ) , new Vector3d ( 2 , 2 , 2 ) ) ;
384+
385+ var closestPoint = BoundingBox . FindClosestPointsBetweenBoxes ( a , b ) ;
386+
387+ Assert . Equal ( new Vector3d ( 1 , - 1 , - 1 ) , closestPoint ) ;
388+ }
389+
390+ [ Fact ]
391+ public void Intersects_WithUnsupportedBound_ReturnsFalse ( )
392+ {
393+ var box = new BoundingBox ( new Vector3d ( 0 , 0 , 0 ) , new Vector3d ( 4 , 4 , 4 ) ) ;
394+ var unsupported = new UnsupportedBound ( new Vector3d ( 10 , 10 , 10 ) , new Vector3d ( 12 , 12 , 12 ) ) ;
395+
396+ Assert . False ( box . Intersects ( unsupported ) ) ;
397+ }
398+
245399 #endregion
246400
247401 #region Test: Serialization
0 commit comments