mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-03-19 08:21:22 +00:00
- NioTSO client isn't needed because we're using RayLib - Added FreeSO's API server to handle most backend operations
115 lines
3.9 KiB
C#
Executable file
115 lines
3.9 KiB
C#
Executable file
using Microsoft.Xna.Framework;
|
|
|
|
namespace FSO.Common.Model
|
|
{
|
|
/// <summary>
|
|
/// A k-d Tree for looking up rectangle intersections
|
|
/// TODO: balancing? could make performance gains more stable at the cost of some of the worst case.
|
|
/// </summary>
|
|
public class IntersectRectTree
|
|
{
|
|
public IntersectRectNode Root;
|
|
|
|
public void Add(Rectangle rect)
|
|
{
|
|
if (Root == null)
|
|
{
|
|
Root = new IntersectRectNode
|
|
{
|
|
Dimension = IntersectRectDimension.Left,
|
|
Rect = rect
|
|
};
|
|
} else
|
|
{
|
|
Root.AddAsChild(rect);
|
|
}
|
|
}
|
|
|
|
public bool SearchForIntersect(Rectangle rect)
|
|
{
|
|
if (Root == null) return false;
|
|
else
|
|
{
|
|
return Root.SearchForIntersect(rect);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class IntersectRectNode
|
|
{
|
|
public IntersectRectNode LeftChild;
|
|
public IntersectRectNode RightChild;
|
|
public IntersectRectDimension Dimension;
|
|
public Rectangle Rect;
|
|
|
|
public void AddAsChild(Rectangle rect)
|
|
{
|
|
bool rightSide = false;
|
|
switch (Dimension)
|
|
{
|
|
case IntersectRectDimension.Top:
|
|
rightSide = rect.Top > Rect.Top; break;
|
|
case IntersectRectDimension.Left:
|
|
rightSide = rect.Left > Rect.Left; break;
|
|
case IntersectRectDimension.Bottom:
|
|
rightSide = rect.Bottom > Rect.Bottom; break;
|
|
case IntersectRectDimension.Right:
|
|
rightSide = rect.Right > Rect.Right; break;
|
|
}
|
|
if (rightSide)
|
|
{
|
|
if (RightChild != null) RightChild.AddAsChild(rect);
|
|
else
|
|
{
|
|
RightChild = new IntersectRectNode
|
|
{
|
|
Dimension = (IntersectRectDimension)(((int)Dimension + 1) % 4),
|
|
Rect = rect
|
|
};
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (LeftChild != null) LeftChild.AddAsChild(rect);
|
|
else
|
|
{
|
|
LeftChild = new IntersectRectNode
|
|
{
|
|
Dimension = (IntersectRectDimension)(((int)Dimension + 1) % 4),
|
|
Rect = rect
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool SearchForIntersect(Rectangle rect)
|
|
{
|
|
if (rect.Intersects(Rect)) return true;
|
|
//search in child nodes.
|
|
int dontSearch = 0;
|
|
switch (Dimension)
|
|
{
|
|
case IntersectRectDimension.Top:
|
|
dontSearch = (rect.Bottom < Rect.Top)?2:0; break; //if true, do not have to search right (where top greater)
|
|
case IntersectRectDimension.Left:
|
|
dontSearch = (rect.Right < Rect.Left)?2:0; break; //if true, do not have to search right (where left greater)
|
|
case IntersectRectDimension.Bottom:
|
|
dontSearch = (rect.Top > Rect.Bottom)?1:0; break; //if true, do not have to search left (where bottom less)
|
|
case IntersectRectDimension.Right:
|
|
dontSearch = (rect.Left > Rect.Right)?1:0; break; //if true, do not have to search left (where right less)
|
|
}
|
|
|
|
//may need to search both :'( won't happen often with our small rectangles over large space though.
|
|
return ((dontSearch != 1 && LeftChild != null && LeftChild.SearchForIntersect(rect))
|
|
|| (dontSearch != 2 && RightChild != null && RightChild.SearchForIntersect(rect)));
|
|
}
|
|
}
|
|
|
|
public enum IntersectRectDimension : byte
|
|
{
|
|
Top,
|
|
Left,
|
|
Bottom,
|
|
Right
|
|
}
|
|
}
|