После долгих исследований и более всего выяснения правильных терминов для Google у меня есть решение, которое я только что встроил в свой тестовый стенд, и оно отлично работает.
Я взял пример, найденный в сети, и проверил его, а затем изменил, чтобы удовлетворить потребности этого вопроса. Следует отметить, что с момента тестирования я внес изменения, так как на этом ноутбуке есть только виртуальная машина, на которой не могут запускаться приложения XNA, поэтому, хотя я уверен, что она должна работать, могут быть ошибки.
Все, что нам нужно сделать, это передать вектор того, где мы находимся, вектор того, где мы хотели бы быть, и границу (которая фактически является линией, состоящей из начального и конечного векторов). Метод скажет нам, пересекаются ли две линии (одна - путь между текущим местоположением и запрошенным местоположением, а другая - граница). В качестве дополнительного бонуса, если они действительно пересекаются, параметр скажет нам, где.
Это очень полезная система для создания мощного обнаружения столкновений.
/// <summary>
/// Based on the 2d line intersection method from "comp.graphics.algorithms Frequently Asked Questions"
/// </summary>
/// <param name="currentLocation">The current location.</param>
/// <param name="requestedLocation">The requested location.</param>
/// <param name="boundary">The boundary.</param>
/// <param name="collisionVector">The collision vector.</param>
/// <returns></returns>
public static bool Intersects(Vector2 currentLocation, Vector2 requestedLocation, Boundary boundary, ref Vector2 collisionVector)
{
float q = (currentLocation.Y - boundary.Start.Y) * (boundary.End.X - boundary.Start.X) - (currentLocation.X - boundary.Start.X) * (boundary.End.Y - boundary.Start.Y);
float d = (requestedLocation.X - currentLocation.X) * (boundary.End.Y - boundary.Start.Y) - (requestedLocation.Y - currentLocation.Y) * (boundary.End.X - boundary.Start.X);
if (d == 0)
{
return false;
}
float r = q / d;
q = (currentLocation.Y - boundary.Start.Y) * (requestedLocation.X - currentLocation.X) - (currentLocation.X - boundary.Start.X) * (requestedLocation.Y - currentLocation.Y);
float s = q / d;
if (r < 0 || r > 1 || s < 0 || s > 1)
{
return false;
}
collisionVector.X = currentLocation.X + (int)(0.5f + r * (requestedLocation.X - currentLocation.X));
collisionVector.Y = currentLocation.Y + (int)(0.5f + r * (requestedLocation.Y - currentLocation.Y));
return true;
}