mirror of
https://github.com/ppy/osu.git
synced 2025-02-22 00:43:25 +08:00
remove tail recursion form welzl
This commit is contained in:
parent
3031b68552
commit
2d95c0b0bb
@ -305,33 +305,37 @@ namespace osu.Game.Utils
|
|||||||
// 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)
|
||||||
{
|
{
|
||||||
// Base case when all points processed or |R| = 3
|
Span<Vector2> r2 = stackalloc Vector2[3];
|
||||||
if (n == 0 || r.Length == 3)
|
int rLength = r.Length;
|
||||||
return minCircleTrivial(r);
|
|
||||||
|
|
||||||
// Pick a random point randomly
|
|
||||||
int idx = RNG.Next(n);
|
|
||||||
Vector2 p = points[idx];
|
|
||||||
|
|
||||||
// Put the picked point at the end of P since it's more efficient than
|
|
||||||
// deleting from the middle of the list
|
|
||||||
(points[idx], points[n - 1]) = (points[n - 1], points[idx]);
|
|
||||||
|
|
||||||
// Get the MEC circle d from the set of points P - {p}
|
|
||||||
var d = welzlHelper(points, r, n - 1);
|
|
||||||
|
|
||||||
// If d contains p, return d
|
|
||||||
if (isInside(d, p))
|
|
||||||
return d;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
Span<Vector2> r2 = stackalloc Vector2[r.Length + 1];
|
|
||||||
r.CopyTo(r2);
|
r.CopyTo(r2);
|
||||||
r2[r.Length] = p;
|
|
||||||
|
|
||||||
// Return the MEC for P - {p} and R U {p}
|
while (true)
|
||||||
return welzlHelper(points, r2, n - 1);
|
{
|
||||||
|
// Base case when all points processed or |R| = 3
|
||||||
|
if (n == 0 || rLength == 3) return minCircleTrivial(r2[..rLength]);
|
||||||
|
|
||||||
|
// Pick a random point randomly
|
||||||
|
int idx = RNG.Next(n);
|
||||||
|
Vector2 p = points[idx];
|
||||||
|
|
||||||
|
// Put the picked point at the end of P since it's more efficient than
|
||||||
|
// deleting from the middle of the list
|
||||||
|
(points[idx], points[n - 1]) = (points[n - 1], points[idx]);
|
||||||
|
|
||||||
|
// Get the MEC circle d from the set of points P - {p}
|
||||||
|
var d = welzlHelper(points, r2[..rLength], n - 1);
|
||||||
|
|
||||||
|
// If d contains p, return d
|
||||||
|
if (isInside(d, p)) return d;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
r2[rLength] = p;
|
||||||
|
rLength++;
|
||||||
|
|
||||||
|
// Return the MEC for P - {p} and R U {p}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
Loading…
Reference in New Issue
Block a user