Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Рисование геометрических фигур




ПРОГРАММИРОВАНИЕ ГРАФИКИ

Цель работы

 

Освоить необходимые средства для написания программ на языке С++, работающих с графикой.

 

Содержание работы

 

1. Изучить основные понятия и функции графического интерфейса операционной системы Microsoft Windows.

2. По предложенному преподавателем варианту разработать функции, рисующие следующие геометрические фигуры:

– незакрашенную фигуру (фигуру-контур),

– закрашенную фигуру,

– две вложенных одну в другую фигуры, внешняя фигура закрашена за исключением пространства внутренней фигуры.

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

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

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

5. Защитить лабораторную работу, ответив на вопросы преподавателя.

Методические указания

 

Контекст отображения

 

Для вывода текста и графики на экран компьютера в операционной системе Microsoft Windows используется интерфейс графических устройств (Graphic Device Interface или GDI). Поскольку интерфейс GDI – весьма сложная компонента, мы будем изучать лишь отдельные его элементы.

Из чего состоит интерфейс GDI с точки зрения приложения?

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

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

Функции рисования не имеют параметров, указывающих цвет или толщину линии. Такие параметры хранятся в контексте отображения.

Чтобы начать работу с контекстом отображения его надо «получить». Получить контекст отображения можно с помощью функции GetDC.

Функция GetDC возвращает контекст отображения (типа HDC) для окна с идентификато­ром hwnd (типа HWND):

 

HWND hwnd;

HDC hdc = GetDC (hwnd);

 

Полученный таким образом контекст отображения можно использовать для рисования во внутренней области окна. Как получить идентификато­р окна hwnd мы рассмотрим в п. 3.5.

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

Функция ReleaseDC освобождает контекст отображения hdc, полученный для окна hwnd:

 

ReleaseDC (hwnd, hdc);

 

Каждый раз, когда приложение получает контекст отображения, его атрибуты принимают значения по умолчанию. Если перед выполнением рисования приложение изменит атрибуты контекста отображе­ния, вызвав соответствующие функции GDI, в следующий раз при получении контекста отображения эти атрибуты снова примут значения по умолчанию. Поэтому установка атрибутов должна выполняться каждый раз после получения контекста отображения.

Полученный контекст отображения имеет систему координат, изображенную на рисунке 1.

 

Рисунок 1.

 

Начало системы координат располагается в левом верхнем углу экрана. Ось X направлена слева направо, ось Y – сверху вниз. В качестве единицы длины используется пиксель. Пиксель (pixel от англ. picture element) – маленькое светящееся пятно. Пиксель является наименьшим элементом изображения дисплеев, в которых изображение складывается из таких отдельных точек.

Для определения размера области окна, в которую можно осуществлять вывод, (точнее, ее координат в пикселях) предназначена функция GetClientRect:

 

RECT rt; //структура с полями left, top, right, bottom

GetClientRect (hwnd, &rt);

 

Координаты записываются во второй параметр, причем поля left, top всегда нулевые, а поля right, bottom содержат соответственно ширину и высоту внутренней области окна:

 

int maxX= rt.right, maxY = rt.bottom;

Инструменты для рисования

 

Перо

 

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

Для выбора встроенного пера лучше всего воспользоваться макрокомандами GetStockPen и SelectPen.

Макрокоманда GetStockPen возвращает идентификатор встроенного пера, (типа HPEN) заданного ее параметром:

 

HPEN hBlackPen = GetStockPen (BLACK_PEN);

 

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

 

Значение Описание
BLACK_PEN Перо, рисующее черную линию толщиной в один пиксель (для любого режима отображения). Это перо выбрано в контекст отображения по умолчанию
WHITE_PEN Перо белого цвета. Толщина пера также равна одному пикселю и не зависит от режима отображения
NULL_PEN Невидимое перо толщиной в один пиксель. Используется для рисования замкнутых закрашенных фигур (таких, как прямоугольник или эллипс) в тех случаях, когда контур фигуры должен быть невидимым

 

После получения идентификатора пера его необходимо выбрать в контекст отображения при помощи макрокоманды SelectPen:

 

HPEN hOldPen;

hOldPen = SelectPen (hdc, hBlackPen);

 

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

Макрокоманда SelectPen возвращает идентификатор пера, который был выбран в контекст отображения раньше. Вы можете сохранить этот идентификатор и использовать его для восстановления старого пера.

Однако при помощи встроенных перьев вы не можете нарисовать цветные, широкие, штриховые и штрихпунктирные линии.

Если вас не устраивают встроенные перья, вы можете легко создать собственные. Для этого нужно воспользоваться функцией CreatePen.

Функция CreatePen позволяет определить стиль, ширину и цвет пера:

 

HPEN hRedPen = CreatePen (PS_SOLID, 3, RGB(255, 0, 0));

 

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

 

Стиль линии Описание
PS_SOLID Сплошная
PS_DASH Пунктирная
PS_DOT Штриховая
PS_DASHDOT Штрихпунктирная, одна точка на одну линию
PS_DASHDOTDOT Штрихпунктирная, две точки на одну линию
PS_NULL Невидимая
PS_INSIDEFRAME Линия, предназначенная для обводки замкнутых фигур

 

Второй параметр определяет ширину пера в пикселях. Учтите, что для линий PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT можно использовать только единичную или нулевую ширину, в обоих случаях ширина линии будет равна одному пикселю.

Третий параметр имеет тип COLORREF и задает цвет пера. Для задания цвета удобно использовать макрокоманду RGB(r, g, b), позволяющую сконструировать цвет из отдельных компонент красного (r), зеленого (g) и голубого (b) цвета, указав в качестве значений параметров интенсивность отдельных цветов в диапазоне от 0 до 255. Например, цвет для красного пера задан нами в виде RGB(255, 0, 0), черный цвет задается как RGB(0, 0, 0), белый – как RGB(255, 255, 255). Три параметра макрокоманды RGB позволяют задать любой из примерно 16 млн. цветов и оттенков.

На первый взгляд линии PS_SOLID и PS_INSIDEFRAME похожи, однако между ними имеются различия, особенно заметные для широких линий. Широкая линия, имеющая стиль PS_SOLID, располагается по обе стороны оси, заданной координатами линии. Линии, имеющие стиль PS_INSIDEFRAME, располагаются внутри контура, определяющего размеры замкнутой фигуры (см. рисунок 2).

 

Рисунок 2.

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

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

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

 

SelectPen (hdc, hOldPen);

DeletePen (hRedPen);

 

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

Продолжая аналогию между контекстом отображения и листом бумаги, на кото­ром рисуются графические изображения и пишется текст, можно сказать, что атрибут цвета фона (background color) в контексте отображения соответствует цвету бумаги. По умолчанию в контексте отображения выбран фон белого цвета.

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

 

SetBkColor (hdc, RGB(0, 0, 0));

COLORREF rgb = GetBkColor (hdc);

 

С помощью трех макрокоманд GetRValue, GetGValue, GetBValue вы можете определить отдельные цветовые компоненты для значения типа COLORREF, возвращаемого функцией GetBkColor

 

printf ("Color is (%d,%d,%d)\n", GetRValue(rgb), GetGValue(rgb),

GetBValue(rgb));

Кисть

Для закрашивания внутренней области окна приложения или замкнутой геометрической фигуры можно использовать кисть (brush) – графические изображения небольшого (8x8 пикселей) размера.

Для выбора одной из встроенных кистей вы можете воспользоваться макроко­мандой GetStockBrush:

 

HBRUSH hBlackBrush = GetStockBrush (BLACK_BRUSH);

 

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

 

Значение Описание
BLACK_BRUSH Кисть черного цвета
WHITE_BRUSH Кисть белого цвета
GRAY_BRUSH Серая кисть
LTGRAY_BRUSH Светло-серая кисть
DKGRAY_BRUSH Темно-серая кисть
NULL_BRUSH Бесцветная кисть, которая ничего не закрашивает
HOLLOW_BRUSH Синоним ДЛЯ NULL_BRUSH

 

Как видно из только что приведенной таблицы, в Windows есть только монохромные встроенные кисти.

Макрокоманда GetStockBrush возвращает идентификатор встроенной кисти.

Прежде чем использовать полученную таким образом кисть, ее надо выбрать в контекст отображения (так же, как и перо). Для этого проще всего воспользоваться макрокомандой SelectBrush:

 

HBRUSH hOldBrush;

hOldBrush = SelectBrush (hdc, hBlackBrush);

 

Макрокоманда SelectBrush возвращает идентификатор старой кисти, выбранной в контекст отображения раньше.

Если вам нужна цветная кисть, ее следует создать с помощью функции CreateSolidBrush:

 

HBRUSH hGreenBrush = CreateSolidBrush (RGB(0, 255, 0));

 

В качестве параметра для этой функции необходимо указать цвет кисти.

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

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

 

SelectBrush (hdc, hOldBrush);

DeleteBrush (hGreenBrush);

 

Приложение может заштриховать внутреннюю область замкнутой фигуры, создав одну из шести кистей штриховки функцией CreateHatchBrush:

 

HBRUSH hCrossBrush = CreateHatchBrush (HS_CROSS, RGB(0, 0, 255));

 

С помощью второго параметра вы можете определить цвет линий штриховки. Первый параметр задает стиль штриховки.

 

Стиль штриховки Внешний вид
HS_BDIAGONAL
HS_CROSS
HS_DIAGCROSS
HS_FDIAGONAL
HS_HORIZONTAL
HS_VERTICAL

 

Рисование геометрических фигур

Рисование точки

 

Функция рисования точки SetPixel устанавливает цвет точки с заданными координатами:

COLORREF rgb = SetPixel (hdc, 10, 10, RGB(255, 0, 255));

Первый параметр определяет контекст отображения, следующие два целочисленных параметра – координаты точки, последний параметр определяет новый цвет точки.

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

Функция GetPixel позволяет узнать цвет точки, заданной идентификатором контекста отображения и координатами:

 

rgb = GetPixel (hdc, 20, 20);

 

С помощью макрокоманд GetRValue, GetGValue, GetBValue (см. п. 3.2.1) вы можете определить отдельные цветовые компоненты для значения, возвращаемого функциями SetPixel и GetPixel.

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

 

Рисование линий

 

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

Текущая позиция пера

 

Для рисования прямых линий (и только для этого) в контексте отображения хранятся координаты текущей позиции пера. Текущая позиция пера – это графический аналог курсора в тек­стовом режиме, только он является невидимым. По умолчанию текущая позиция пера равна значению (0, 0).

Для изменения текущей позиции пера служит функция MoveToEx:

 

POINT pt;

BOOL bxt = MoveToEx (hdc, x, y, &pt);

 

Для контекста отображения hdc эта функция устанавливает текущую позицию пера, равную (х, у). В структуру типа POINT (имеет два целочисленных поля х, у), на которую указывает последний параметр, после возврата из функции будут записаны старые координаты пера. Если вам не нужно предыдущее текущее положение пера, вы можете просто установить последний параметр в NULL. MoveToEx возвращает TRUE при нормальном завершении и FALSE при ошибке.

Чтобы узнать текущую позицию пера, приложение может использовать функцию GetCurrentPositionEx:

 

bxt = GetCurrentPositionEx (hdc,&pt);

 

После вызова этой функции текущая позиция пера будет записана в структуру типа POINT, на которую указывает последний параметр. Функция возвращает TRUE при нормальном завершении или FALSE при ошибке.


Рисование прямой линии

 

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

 

bxt = LineTo (hdc, xEnd, yEnd);

 

Эта функция рисует линию из текущей позиции пера, установленной ранее функцией MoveToEx, в точку с координатами (xEnd, yEnd). После того как линия будет нарисована, текущая позиция пера станет равной (xEnd, yEnd).

Функция LineTo возвращает TRUE при нормальном завершении или FALSE при ошибке.

Таким образом, для того чтобы нарисовать прямую линию, приложение должно сначала с помощью функции MoveToEx установить текущую позицию пера в точку, которая будет началом линии, а затем вызвать функцию LineTo, передав ей через параметры xEnd и yEnd координаты конца линии.

Особенностью функции LineTo является то, что она немного не дорисовывает линию – эта функция рисует всю линию, не включая ее конец, то есть точку (xEnd, yEnd). Это иллюстрирует рисунок 3.

 

Рисунок 3.

 

Нарисуем с помощью рассмотренных функций красный прямоугольник.

 

SelectPen (hdc, hRedPen);

MoveToEx (hdc, 100, 100,&pt);

LineTo (hdc, 100, 200);

LineTo (hdc, 200, 200);

LineTo (hdc, 200, 100);

LineTo (hdc, 100, 100);

 


Рисование ломаной линии

 

Функции Polyline, предназначенной для рисования ломаных линий, следует передать идентификатор контекста отображения hdc, указатель на массив структур POINT, в котором должны находиться координаты начала ломаной линии, координаты точек излома и координаты конца ломаной линии, а также размер этого массива:

 

POINT ppt[4]={ {100,100}, {200,200}, {100,300}, {100,100} };

bxt = Polyline (hdc, ppt, 4);

 

Функция возвращает TRUE при нормальном завершении или FALSE при ошибке. Она не использует текущую позицию пера и не изменяет ее.

Если ломаная линия не замкнута, ее последняя точка не рисуется (см. рисунок 4).

 

Рисунок 4.

 

Закраска фигур

 

Если вы нарисовали замкнутую геометрическую фигуру, то можно закрасить ее внутреннюю область. Для этого служит функция FloodFill:

 

bxt = FloodFill (hdc, nX, nY, RGB(0, 255, 255));

 

Для функции FloodFill необходимо указать идентификатор контекста отображения hdc, координаты точки внутри области nX, nY и цвет контура, ограничивающего область.

Функция возвращает TRUE при успешном завершении или FALSE при ошибке (ошибка возникает, например, в том случае, когда цвет точки (nX, nY) совпадает с цветом контура).

Если контур, ограничивающий область, окажется незамкну­тым, краска «прольется» на остальную часть экрана.

Для закраски используется кисть, выбранная в контекст отображения.

Таким же образом можно закрасить и внутреннюю область окна приложения.

Для рисования закрашенных фигур можно воспользоваться также функциями, описанными в п. 3.3.3.

 

Рисование замкнутых фигур

 

Помимо линий приложения Windows могут использовать функции GDI для рисования замкнутых закрашенных или незакрашенных фигур, таких, как пря­моугольники, эллипсы, сегменты и сектора эллипсов, многоугольники с прямыми и скругленными углами и т. д.

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

Рисование прямоугольника

 

Простейшая функция, с помощью которой можно нарисовать прямоугольник, называется Rectangle:

 

bxt = Rectangle (hdc, x1, y1, x2, y2);

 

Функция Rectangle рисует прямоугольник для контекста отображения hdc, возвращая значение TRUE в случае успеха или FALSE при ошибке. Назначение остальных параметров иллюстрирует рисунок 5.

 

Рисунок 5.

 

Как видно из этого рисунка, последние четыре параметра функции задают координаты левого верхнего и правого нижнего углов прямоугольника.

В зависимости от стиля пера граница фигуры может находиться полностью внутри прямоугольника, заданного координатами (x1, y1), (x2, y2), или выходить за пределы (рисунок 2). Если выбрать стиль пера PS_NULL, граница фигуры станет невидимой.

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

Рисование эллипса

 

Для рисования эллипса вы можете использовать функцию Ellipse:

 

bxt = Ellipse (hdc, x1, y1, x2, y2);

 

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

 

Рисунок 6.

Рисование многоугольников

 

Рисование многоугольников (рисунок 7) выполняется функцией Polygon, аналогичной по своим параметрам функции Polyline, с помощью которой рисуются ломаные линии:

 

bxt = Polygon (hdc, ppt, 3);

 

Через параметр hdc передается идентификатор контекста отображения. Второй параметр указывает на массив структур POINT, в котором должны находиться координаты вершин многоугольника. Третий параметр определяет размер этого массива.

Функция Polygon возвращает TRUE при нормальном завершении или FALSE при ошибке. Она не использует текущую позицию пера и не изменяет ее.

 

Рисунок 7.

 

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

Вывод текста

 

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

 

bxt = TextOutA (hdc, xStart, yStart, PStr, lenstr);

 

Первый параметр (hdc) определяет используемый контекст отображения. Второй (xStart) и третий (yStart) параметры задают координаты (х, у) начальной позиции, начиная с которой будет выполняться вывод текста.

Четвертый параметр (PStr) является указателем на выводимую строку, длина которой определяется последним, пятым параметром (lenstr).

Как нетрудно заметить, функция TextOutA не имеет параметров, определяющих шрифт, размер букв, цвет фона, цвет букв и т. п. Все эти характеристики текста хранятся в структуре контекста отображения и могут изменяться. Мы рассмотрим лишь выбор цвета букв. Для этого необходимо вызвать функцию SetTextColor:

 

COLORREF Old_rgb = SetTextColor (hdc, rgb);

 

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

В любой момент времени вы можете определить текущий цвет, используемый для вывода текста. Для этого следует вызвать функцию GetTextColor:

 

rgb = GetTextColor (hdc);

 

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

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...