Правильно вычислить ограничивающую рамку для преобразованного прямоугольника с помощью System.Numerics

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

public static Rectangle GetBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix)
{
    Vector2 leftTop = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Top), matrix);
    Vector2 rightTop = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Top), matrix);
    Vector2 leftBottom = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Bottom), matrix);
    Vector2 rightBottom = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Bottom), matrix);

    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 new Rectangle(0, 0, (int)(max.X - min.X), (int)(max.Y - min.Y));
}

Он хорошо работает с вращением, но не с перекосом. Как видно из изображений ниже, прямоугольник, рассчитанный по формуле, слишком мал. Может ли кто-нибудь определить, в чем проблема, или уже есть метод в пространстве имен System.Numerics, который я могу использовать?

Поворот — матричная формула

Matrix3x2.CreateRotation(radians, origin)

Повернутое изображение с правильной ограничительной рамкой

Перекос — матричная формула

Matrix3x2.CreateRotation(radiansX, radiansY, origin)

Перекошенное изображение с неправильной ограничивающей рамкой


person James South    schedule 31.05.2016    source источник


Ответы (1)


Я не совсем уверен, в чем проблема с тем, что вы сделали, но это не самое надежное определение ограничивающей рамки, а именно:

var allCorners = new List<Vector2> { leftTop, rightTop, leftBottom, rightBottom };
var xExtent = allCorners.Select(v => v.X).Max() - allCorners.Select(v => v.X).Min();
var yExtent = allCorners.Select(v => v.Y).Max() - allCorners.Select(v => v.Y).Min();
return new Rectangle(0, 0, xExtent, yExtent);
person James Ellis-Jones    schedule 31.05.2016
comment
Я думаю, что мы оба возвращаем один и тот же результат, который соответствует тесту JavaScript здесь. формула может быть действительно правильной. Как ни странно, он просто не кажется достаточно большим. - person James South; 31.05.2016