Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Graph.doc
Скачиваний:
19
Добавлен:
14.05.2015
Размер:
238.59 Кб
Скачать

Режим отображения

До сих пор, говоря о задании координат, мы подразумевали, что речь идет о смещении относительно левого верхнего угла экрана (screen coordinates) или левого верхнего угла клиентской области окна (client coordinates). В принципе, для всего, что касается окон в целом и оконных сообщений, например, WM_MOVE, WM_MOUSEMOVE, это правильно. Однако всегда ли удобно рисовать линию "по точкам", когда, во-первых, все перевернуто с ног на голову – координаты по вертикали растут вниз, во-вторых, приходится постоянно заботиться о масштабе и, в-третьих, приходится помнить формулы вычисления координат точек при повороте и смещении?

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

Настройка режимов отображения

Функции этой группы устанавливают и настраивают систему координат, которая используется всеми функциями вывода: координаты вывода задаются именно в логических единицах. Кроме единиц по осям хну, функции этой группы задают направление осей и начало координат. Практически все Функции реализованы парами: функции с префиксом Get позволяют получить текущее значение параметра, а с префиксом Set устанавливают новое значение и возвращают предыдущее. По умолчанию начало координат находится в левом верхнем углу области вывода (прежде всего окна), ось х направлена слева направо, а ось у сверху вниз. Единица измерения – один пиксел (режим ММ_ТЕХТ). Кстати сказать, именно поэтому на различных устройствах из-за различий в размерах пиксела фактический (визуальный) размер по оси х может не соответствовать размеру по оси у.

Для настройки системы координат Windows использует два понятия – физическая область вывода (viewport), координаты и размеры которой задаются в физических единицах – пикселах, и логическая область вывода (window) координаты и размеры которой задаются в логических единицах, определяемых режимом рисования.

Давайте теперь познакомимся с режимами отображения, поддерживаемыми Windows. Всего их восемь, и основная функция, которая позволяет выбрать режим, а значит, и систему координат – SetMapMode:

virtual int CDC::SetMapMode(int nMapMode)

Эта функция устанавливает направления осей и определяет логические единицы, т.е. единицы измерения для задаваемой системы координат. Возможные режимы задаются параметром nMapMode, который принимает следующие значения:

ММ_ТЕХТ

Одна логическая единица равна одному пикселу, ось х направлена вправо, ось у – вниз; режим задан по умолчанию

MM_HIENGLISH

Одна логическая единица равна 0.001 дюйма, ось х направлена вправо, ось у – вверх

MM_HIMETRIC

Одна логическая единица равна 0.01 миллиметра, ось х направлена вправо, ось у – вверх

MM_LOENGLISH

Одна логическая единица равна 0.01 дюйма, ось х направлена вправо, ось у – вверх

MM_LOMETRIC

Одна логическая единица равна 0.1 миллиметра, ось х направлена вправо, ось у – вверх

MM_TWIPS

Одна логическая единица – твипс (twips) – равна 1/20 пункта (point) или 1/1440 дюйма, ось х направлена вправо, ось у – вверх

MM_ANISOTROPIC

Режим позволяет настраивать (с помощью функций SetWindowExt и SetViewportExt) размерность (отдельно для каждой из осей), их направления и начало отсчета

MM_ISOTROPIC

Режим позволяет настраивать (с помощью функций SetWindowExt и SetViewportExt) размерность осей, их направления и начало отсчета, однако единица оси x равна единице оси у, т. е. при необходимости GDI настраивает размерность по осям, обеспечивая соотношение 1:1

Исторически в полиграфии используются такие единицы измерения, как пункты (points) и твипсы (twips), размеры которых составляют (приблизительно) 1/72 и 1/1440 дюйма, соответственно. Для обозначения точки экрана мы используем понятие пиксел (pixel).

Отметим, что только режимы MM_TWIPS, MM_HIENGLISH, MM_HIMETRIC, MM_LOENGLISH и MM_LOMETRIC обеспечивают приложения, с одной стороны, физически понятными единицами измерения, а другой – определенной независимостью от устройств вывода.

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

И физическая, и логическая области вывода характеризуются точкой, определяющей начало координат. Для настройки начала координат физической области вывода используются функции:

virtual CPoint CDC::SetViewportOrg(int x, int y)

или

virtual CPoint CDC::SetViewportOrg (POINT point).

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

CPoint CDC::SetWindowOrg(int x, int у)

или

CPoint CDC::SetWindowOrg(POINT point).

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

Из вышесказанного следует, что настраивать начало координатной сетки есть смысл только для одной из областей, т.к. система координат логической области вывода привязана к системе координат физической области. Поясним сказанное на примерах.

После настроек функции OnPaint классов CVenusFrame и CEarthFrame будут работать с координатной сеткой, начало координат которой располагается в середине клиентской области (рис. 4).

void CVenusFrame::OnPaint() {

CPaintDC dc(this);

CRect rect;

GetClientRect(rect);

dc.SetViewportOrg(rect.Width()/2, rect.Height(}/2);

}

void CEarthFrame::OnPaint() {

CPaintDC dc(this);

CRect rect;

GetClientRect(rect);

dc.DPtoLP(rect);

dc.SetWindowOrg(-rect.Width()/2, -rect.Height()/2);

}

В следующем примере попытка настройки систем координат обеих областей вывода в классе CMarsFrame приводит к несколько неожиданным результатам (рис. 5), так что такую последовательность, скорее всего, можно считать ошибочной.

void CMarsFrame::OnPaint() {

CPaintDC dc(this);

CRect rect;

GetClientRect(rect);

dc.SetViewportOrg(rect.Width()/2, rect.Height()/2);

// Вызовы следующих двух функций необходимы в случае,

// если текущий режим отличен от ММ_ТЕХТ (см. далее),

// т.к. функция SetWindowOrg работает с логическими

// координатами, а в результате преобразования из-за

// несоответствия направления осей длина и ширина области

// могут быть вычислены неверно

dc.DPtoLP(rect);

rect.NormalizeRect();

dc.SetViewportOrg(-rect.Width()/2, -rect.Height()/2);

. . .

}

Кроме начала координат, каждая из областей вывода характеризуется еще, что вполне естественно, размерами (extents), которые используются только доя определения коэффициента масштабирования. Коэффициент для каждой из осей находится как отношение соответствующих размеров областей вывода. Однако для большинства режимов отображения коэффициент масштабирования изменить невозможно.

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

Для настройки размеров физической области вывода используются функции:

virtual CSize CDC::SetViewportExt(int cx,int cy)

или

virtual CSize CDC::SetViewportExt(SIZE size).

Для настройки размеров логической области вывода используются функции:

virtual CSize CDC::SetWindowExt(int cx, int cy)

или

virtual CSize CDC::SetWindowExt(SIZE size).

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

Ниже приводится код, который помещает начало координат в середину клиентской области окна, ось у направлена вверх, а минимальный из размеров по горизонтали или вертикали равен 200 логическим единицам (рис. 6). При этом вывод может осуществляться и по координатам, большим 100 или меньшим – 100, соответственно.

РежимMM_ISOTROPIC предполагает отношение единиц по обоим направлениям как 1:1. Таким образом, задание одинаковых размеров области вывода в окне, имеющем прямоугольную форму (не квадрат), приводит к тому, что по одной из осей фактически размер области вывода может быть больше заданного. С другой стороны, никто не запрещает вызывать функции рисования вне клиентской области окна – они не окажут влияния на другие окна.

void CSaturnFrame::OnPaint() {

CPaintDC dc(this);

CRect rect;

GetClientRect(rect);

dc.SetMapMode(MM_ISOTROPIC);

dc.SetWindowExt(100,100);

dc.SetViewportExt(rect.Width(), -rect.Height());

dc.SetViewportOrg(rect.Width()/2,rect.Height()/2);

}

Кроме вышеперечисленных функций для установки начала координат и размеров осей, класс CDC содержит ряд функций для модификации текущих установок.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]