Поделиться через


Почему порядок преобразования является значительным

Один объект Matrix может хранить одно преобразование или последовательность преобразований. Последний называется составным преобразованием . Матрица составного преобразования получается путем умножения матриц отдельных преобразований.

В составном преобразовании порядок отдельных преобразований важен. Например, если сначала повернуть, затем масштабировать и затем сместить, вы получите другой результат, чем если сначала сместить, затем повернуть, а потом масштабировать. В Windows GDI+составные преобразования создаются слева направо. Если S, R и T являются матрицами масштабирования, поворота и преобразования соответственно, то SRT продукта (в этом порядке) представляет собой матрицу составного преобразования, который сначала масштабируется, а затем поворачивается, а затем преобразуется. Матрица, созданная продуктом SRT, отличается от матрицы, созданной TRS продукта.

Одна из причин, почему порядок важен, заключается в том, что преобразования, такие как поворот и масштабирование, выполняются относительно начала координат. Масштабирование объекта, центрированного в источнике, создает другой результат, отличный от масштабирования объекта, который был удален из источника. Аналогичным образом поворот объекта, который находится в центре источника, создает другой результат, отличный от поворота объекта, который был удален из источника.

В следующем примере объединяется масштабирование, поворот и преобразование (в этом порядке) для формирования составного преобразования. Аргумент MatrixOrderAppend, переданный методу Graphics::RotateTransform указывает, что поворот будет следовать масштабированию. Аналогичным образом аргумент MatrixOrderAppend, переданный методу Graphics::TranslateTransform указывает, что перевод будет следовать повороту.

Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.ScaleTransform(1.75f, 0.5f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.TranslateTransform(150.0f, 150.0f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);

Следующий пример выполняет те же вызовы метода, что и предыдущий пример, но порядок вызовов изменен на противоположный. Результирующий порядок операций: сначала переводится, затем вращается, затем масштабируется, что приводит к совершенно иному результату, чем сначала масштабировать, затем вращать, затем переводить.

Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);

Один из способов изменить порядок отдельных преобразований в составном преобразовании — изменить порядок последовательности вызовов методов. Вторым способом управления порядком операций является изменение аргумента порядка матрицы. Следующий пример совпадает с предыдущим примером, за исключением того, что MatrixOrderAppend было изменено на MatrixOrderPrepend. Умножение матрицы выполняется в порядке SRT, где S, R и T являются матрицами для масштабирования, поворота и перевода соответственно. Порядок составного преобразования: сначала масштабирование, затем поворот, затем перемещение.

Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f,MatrixOrderPrepend);
graphics.RotateTransform(28.0f, MatrixOrderPrepend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderPrepend);
graphics.DrawRectangle(&pen, rect);

Результатом предыдущего примера является тот же результат, который мы достигли в первом примере этого раздела. Это связано с тем, что мы изменили порядок вызовов метода и порядок умножения матрицы.