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


Глобальные и локальные преобразования

Глобальное преобразование — это преобразование, которое применяется ко всем элементам, нарисованным заданным графическим объектом. Чтобы создать глобальное преобразование, создайте объект Graphics , а затем вызовите его метод Graphics::SetTransform . Метод Graphics::SetTransform управляет объектом Matrix , связанным с объектом Graphics . Преобразование, хранящееся в этом объекте Matrix , называется преобразованием мира. Преобразование мира может быть простым аффинным преобразованием или сложной последовательностью аффинных преобразований, но независимо от сложности преобразование мира хранится в одном объекте Matrix .

Класс Graphics предоставляет несколько методов для создания составного преобразования мира: Graphics::MultiplyTransform, Graphics::RotateTransform, Graphics::ScaleTransform и Graphics::TranslateTransform. В следующем примере дважды рисуется эллипс: один раз до создания преобразования мировых координат и один раз после. Преобразование сначала масштабируется на коэффициент 0,5 в направлении y, а затем преобразует 50 единиц в направлении x, после чего поворачивает на 30 градусов.

myGraphics.DrawEllipse(&myPen, 0, 0, 100, 50);
myGraphics.ScaleTransform(1.0f, 0.5f);
myGraphics.TranslateTransform(50.0f, 0.0f, MatrixOrderAppend);
myGraphics.RotateTransform(30.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myPen, 0, 0, 100, 50);

На следующем рисунке показаны исходный эллипс и преобразованный эллипс.

снимок экрана: окно с двумя перекрывающимися многоточиями; один из них является более узким и повернут

Примечание

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

 

Локальное преобразование — это преобразование, которое применяется к конкретному отрисовываемого элементу. Например, объект GraphicsPath имеет метод GraphicsPath::Transform , который позволяет преобразовывать точки данных этого пути. В следующем примере рисуются прямоугольник без преобразования и путь с преобразованием поворота. (Предположим, что преобразования мировых координат не происходит)

 
Matrix myMatrix;
myMatrix.Rotate(45.0f);
myGraphicsPath.Transform(&myMatrix);
myGraphics.DrawRectangle(&myPen, 10, 10, 100, 50);
myGraphics.DrawPath(&myPen, &myGraphicsPath);

Вы можете совмещать преобразование мировых координат с локальными преобразованиями для достижения различных результатов. Например, можно использовать преобразование мировых координат для изменения системы координат, а затем использовать локальные преобразования для поворота и масштабирования объектов, нарисованных в новой системе координат.

Предположим, что вам требуется система координат, имеющая начало в позиции 200 пикселей от левого края клиентской области и 150 пикселей от верхней части клиентской области. Кроме того, предположим, что единица измерения должна быть равна пикселю, а оси x и y — указывать вправо и вверх соответственно. В системе координат по умолчанию ось y указывает вниз, поэтому необходимо выполнить отражение по горизонтальной оси. На следующем рисунке показана матрица такого отражения.

Иллюстрация, показывающая матрицу

Затем предположим, что необходимо выполнить преобразование 200 единиц направо и 150 единиц вниз.

В следующем примере устанавливается только что описанная система координат путем задания преобразования мира объекта Graphics .

Matrix myMatrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
myGraphics.SetTransform(&myMatrix);
myGraphics.TranslateTransform(200.0f, 150.0f, MatrixOrderAppend);

Следующий код (расположенный после кода в предыдущем примере) создает путь, состоящий из одного прямоугольника с его нижним левым углом в начале новой системы координат. Прямоугольник заполняется один раз без локального преобразования и один раз с локальным преобразованием. Локальное преобразование состоит из горизонтального масштабирования на коэффициент 2, за которым следует поворот в 30 градусов.

// Create the path.
GraphicsPath myGraphicsPath;
Rect myRect(0, 0, 60, 60);
myGraphicsPath.AddRectangle(myRect);

// Fill the path on the new coordinate system.
// No local transformation
myGraphics.FillPath(&mySolidBrush1, &myGraphicsPath);

// Transform the path.
Matrix myPathMatrix;
myPathMatrix.Scale(2, 1);
myPathMatrix.Rotate(30, MatrixOrderAppend);
myGraphicsPath.Transform(&myPathMatrix);

// Fill the transformed path on the new coordinate system.
myGraphics.FillPath(&mySolidBrush2, &myGraphicsPath);

На следующем рисунке показаны новая система координат и два прямоугольника.

Снимок экрана оси X и Y и синий квадрат, наложенный полупрозрачной прямоугольником, повернутый вокруг левого нижнего угла