C
C#2y ago
arch_il

❔ Part of me feels like I need to learn System.Linq; one day

float[] overlaps = new float[]
{
second.Left - first.Right, // left
second.Right - first.Left, // right
second.Top - first.Bottom, // top
second.Bottom - first.Top // bottom
};

if (overlaps[0] <= 0 && overlaps[1] >= 0 && overlaps[2] <= 0 && overlaps[3] >= 0)
{
float min = overlaps.Min(x => Math.Abs(x));

if (min == Math.Abs(overlaps[0]))
return new Vector2(overlaps[0], 0);
else if (min == Math.Abs(overlaps[1]))
return new Vector2(overlaps[1], 0);
else if (min == Math.Abs(overlaps[2]))
return new Vector2(0, overlaps[2]);
else if (min == Math.Abs(overlaps[3]))
return new Vector2(0, overlaps[3]);
}

return Vector2.Zero;
float[] overlaps = new float[]
{
second.Left - first.Right, // left
second.Right - first.Left, // right
second.Top - first.Bottom, // top
second.Bottom - first.Top // bottom
};

if (overlaps[0] <= 0 && overlaps[1] >= 0 && overlaps[2] <= 0 && overlaps[3] >= 0)
{
float min = overlaps.Min(x => Math.Abs(x));

if (min == Math.Abs(overlaps[0]))
return new Vector2(overlaps[0], 0);
else if (min == Math.Abs(overlaps[1]))
return new Vector2(overlaps[1], 0);
else if (min == Math.Abs(overlaps[2]))
return new Vector2(0, overlaps[2]);
else if (min == Math.Abs(overlaps[3]))
return new Vector2(0, overlaps[3]);
}

return Vector2.Zero;
This is simple collision I wrote in few minutes for my game. I feel like I don't need to use Math.Abs() 2 times, first to find and then to compare to number. Can I find index of minimum value using Linq in some simple fancy one liner way?
3 Replies
JakenVeina
JakenVeina2y ago
return ( (second.Left < first.Right)
&& (second.Right > first.Left)
&& (second.Top < first.Bottom)
&& (second.Bottom > first.Top))
? Enumerable.Empty<Vector2>()
.Append(new Vector2(second.Left - first.Right, 0))
.Append(new Vector2(second.Right - first.Left, 0))
.Append(new Vector2(0, second.Top - first.Bottom))
.Append(new Vector2(0, second.Bottom - first.Top))
.Aggregate((x, y) => (x.Length < y.Length) ? x : y)
: Vector2.Zero;
return ( (second.Left < first.Right)
&& (second.Right > first.Left)
&& (second.Top < first.Bottom)
&& (second.Bottom > first.Top))
? Enumerable.Empty<Vector2>()
.Append(new Vector2(second.Left - first.Right, 0))
.Append(new Vector2(second.Right - first.Left, 0))
.Append(new Vector2(0, second.Top - first.Bottom))
.Append(new Vector2(0, second.Bottom - first.Top))
.Aggregate((x, y) => (x.Length < y.Length) ? x : y)
: Vector2.Zero;
not that this is a good approach at all, but if you want one-liners...
arch_il
arch_ilOP2y ago
float min = overlaps.Min(x => Math.Abs(x));

if (min == Math.Abs(overlaps[0]))
return new Vector2(overlaps[0], 0);
else if (min == Math.Abs(overlaps[1]))
return new Vector2(overlaps[1], 0);
else if (min == Math.Abs(overlaps[2]))
return new Vector2(0, overlaps[2]);
else if (min == Math.Abs(overlaps[3]))
return new Vector2(0, overlaps[3]);
float min = overlaps.Min(x => Math.Abs(x));

if (min == Math.Abs(overlaps[0]))
return new Vector2(overlaps[0], 0);
else if (min == Math.Abs(overlaps[1]))
return new Vector2(overlaps[1], 0);
else if (min == Math.Abs(overlaps[2]))
return new Vector2(0, overlaps[2]);
else if (min == Math.Abs(overlaps[3]))
return new Vector2(0, overlaps[3]);
I just wanted to avoid calling Math.Abs() function twice for no reason. I found this solution:
var (minValue, minIndex) = overlaps.Select((x, i) => (Math.Abs(x), i)).Min();

switch (minIndex)
{
case 0:
return new Vector2(overlaps[0], 0);
case 1:
return new Vector2(overlaps[1], 0);
case 2:
return new Vector2(0, overlaps[2]);
case 3:
return new Vector2(0, overlaps[3]);
}
var (minValue, minIndex) = overlaps.Select((x, i) => (Math.Abs(x), i)).Min();

switch (minIndex)
{
case 0:
return new Vector2(overlaps[0], 0);
case 1:
return new Vector2(overlaps[1], 0);
case 2:
return new Vector2(0, overlaps[2]);
case 3:
return new Vector2(0, overlaps[3]);
}
Is this better than original code? I am only using Math.Abs() once to find the index of min number and using switch instead of if else if chain. It should be faster than original.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server