Столкновения в САТ работают только в двух направлениях
Я пытаюсь разрешить коллизии через SAT в XNA, но это работает только в двух направлениях внизу и справа). Я полагаю, что эта проблема вызвана тем, что перекрытие не проходит проверку длины, если ось имеет отрицательные компоненты.
Метод разрешения столкновений:
public Vector2 Collides(Rect other, float selfr, float otherr)
{
Vector2 minTranslationVector = new Vector2(Single.PositiveInfinity, Single.PositiveInfinity);
foreach (Vector2 v in GetRotatedNormals(selfr))
{
float[] minMaxA = ProjectRotatedAlongAxis(selfr, v);
float[] minMaxB = other.ProjectRotatedAlongAxis(otherr, v);
float minA = minMaxA[0];
float maxA = minMaxA[1];
float minB = minMaxB[0];
float maxB = minMaxB[1];
if (!(maxA > minB && maxB > minA))
return new Vector2(0, 0);
float overlap = Math.Min(maxA - minB, maxB - minA);
if (Math.Pow(overlap, 2) < minTranslationVector.LengthSquared())
{
minTranslationVector = v * overlap;
}
}
foreach (Vector2 v in other.GetRotatedNormals(otherr))
{
float[] minMaxA = ProjectRotatedAlongAxis(selfr, v);
float[] minMaxB = other.ProjectRotatedAlongAxis(otherr, v);
float minA = minMaxA[0];
float maxA = minMaxA[1];
float minB = minMaxB[0];
float maxB = minMaxB[1];
if (!(maxA > minB && maxB > minA))
return new Vector2(0, 0);
float overlap = Math.Min(maxA - minB, maxB - minA);
if (Math.Pow(overlap, 2) < minTranslationVector.LengthSquared())
{
minTranslationVector = v * overlap;
}
}
return minTranslationVector;
}
Разрешение столкновений игроков (фрагмент из метода обновления)
foreach (GameObject obj in room.Objects)
{
if (!obj.HasCollisions)
continue;
Rect playerRect = new Rect(BoundingBox);
Vector2 minTranslationVector = playerRect.Collides(new Rect(obj.BoundingBox), 0, 0);
playerRect.topLeft += minTranslationVector;
toDraw += playerRect.isNegative;
Position = playerRect.topLeft;
BoundingBox = playerRect.ToRectangle();
}