Как проверить, пересекает ли точка AABB для пользовательского 2D физического движка - PullRequest
1 голос
/ 23 декабря 2011

Я не нашел способа создать AABB для двухстороннего столкновения в Google, и мне было интересно, как работает его математика. Я думал, что мог бы использовать какие-то матричные преобразования, чтобы достичь этого, но эта идея провалилась эпически. В общем, я хочу знать о любом ресурсе, который может помочь мне создать ограничивающий прямоугольник и проверить, пересекает ли точка его, или объяснить его математику и логику.

Редактировать: я не знаю, дал ли я это понять, но мне нужно проверить столкновения с ними. Просто чтобы прояснить это.

1 Ответ

1 голос
/ 29 декабря 2011

Проверка пересечения между двумя прямоугольниками не позволяет проверять повернутый прямоугольник.Функция простого пересечения не будет работать.Ваша идея расчета прямоугольника, который включает в себя ваш «фактический» повернутый прямоугольник, а затем вместо этого проверять наличие столкновений в ограничивающих прямоугольниках.

Вот некоторый код, который будет возвращать прямоугольник на основе другого прямоугольника и преобразования матрицы вращения:

public static Rectangle CalculateBoundingRectangle(Rectangle rectangle, Matrix transform)
{
    // Get all four corners in local space
    Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top);
    Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top);
    Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom);
    Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom);

    // Transform all four corners into work space
    Vector2.Transform(ref leftTop, ref transform, out leftTop);
    Vector2.Transform(ref rightTop, ref transform, out rightTop);
    Vector2.Transform(ref leftBottom, ref transform, out leftBottom);
    Vector2.Transform(ref rightBottom, ref transform, out rightBottom);

    // Find the minimum and maximum extents of the rectangle in world space
    Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop),
                                Vector2.Min(leftBottom, rightBottom));
    Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop),
                                Vector2.Max(leftBottom, rightBottom));

    // Return that as a rectangle
    return new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y));
}

Конечно, этот тип обнаружения столкновений быстрый, но не точный.Ваш ограничивающий прямоугольник не будет 1: 1 представлением вашей фигуры.Если вам нужна большая точность, вы можете использовать проверку столкновений на пиксель после проверки с помощью AABB.

Этот ответ также может вас заинтересовать, особенно ответ по SAT.

...