1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-22 19:12:56 +08:00

remove tail recursion form welzl

This commit is contained in:
OliBomby 2024-09-24 18:45:52 +02:00
parent 3031b68552
commit 2d95c0b0bb

View File

@ -304,10 +304,15 @@ namespace osu.Game.Utils
// points on the circle boundary. // points on the circle boundary.
// n represents the number of points in P that are not yet processed. // n represents the number of points in P that are not yet processed.
private static (Vector2, float) welzlHelper(List<Vector2> points, ReadOnlySpan<Vector2> r, int n) private static (Vector2, float) welzlHelper(List<Vector2> points, ReadOnlySpan<Vector2> r, int n)
{
Span<Vector2> r2 = stackalloc Vector2[3];
int rLength = r.Length;
r.CopyTo(r2);
while (true)
{ {
// Base case when all points processed or |R| = 3 // Base case when all points processed or |R| = 3
if (n == 0 || r.Length == 3) if (n == 0 || rLength == 3) return minCircleTrivial(r2[..rLength]);
return minCircleTrivial(r);
// Pick a random point randomly // Pick a random point randomly
int idx = RNG.Next(n); int idx = RNG.Next(n);
@ -318,20 +323,19 @@ namespace osu.Game.Utils
(points[idx], points[n - 1]) = (points[n - 1], points[idx]); (points[idx], points[n - 1]) = (points[n - 1], points[idx]);
// Get the MEC circle d from the set of points P - {p} // Get the MEC circle d from the set of points P - {p}
var d = welzlHelper(points, r, n - 1); var d = welzlHelper(points, r2[..rLength], n - 1);
// If d contains p, return d // If d contains p, return d
if (isInside(d, p)) if (isInside(d, p)) return d;
return d;
// Otherwise, must be on the boundary of the MEC // Otherwise, must be on the boundary of the MEC
// Stackalloc to avoid allocations. It's safe to assume that the length of r will be at most 3 // Stackalloc to avoid allocations. It's safe to assume that the length of r will be at most 3
Span<Vector2> r2 = stackalloc Vector2[r.Length + 1]; r2[rLength] = p;
r.CopyTo(r2); rLength++;
r2[r.Length] = p;
// Return the MEC for P - {p} and R U {p} // Return the MEC for P - {p} and R U {p}
return welzlHelper(points, r2, n - 1); n--;
}
} }
#endregion #endregion