Программа 32. российский флаг
Программа изображает на экране Российский флаг. Изображение флага создает функция RussFlag путем образования трех текстовых окон, у которых цвета фона устанавливаются в соответствии с цветами флага.
По умолчанию на экране используется черный (BLACK) цвет для фона и светло-серый (LIGHTGRAY) цвет для символов. Функция RussFlag изменяет цветовые установки, поэтому они восстанавливаются в функции NormScreen.
// Файл RussFlag.cpp
// Программа изображает на экране флаг России
#include <conio.h>
#include <iostream.h>
#include <stdlib.h>
double HW = 14.0/9.0;// Отношение высоты к ширине одного знакоместа
// RussFlag: изображает флаг России
void RussFlag(int x, int y, int h)
{ // x, y - координаты левого верхнего угла флага
// h - высота одной цветовой полосы
int w; // Длина флага
w = h * 3 * 2 * HW; // Флаг состоит из трех цветных полос,
// его длина в 2 раза больше высоты
// Множитель HW дает поправку,
// так как на экране в текстовом режиме
// высота знакоместа больше ширины
// Создаем изображение на экране
window(x, y, x + w, y + h - 1); // Окно для белой полосы флага
textbackground(LIGHTGRAY);
clrscr();
window(x, y + h, x + w, y + 2 * h - 1); // Окно для голубой полосы
textbackground(BLUE);
clrscr();
window(x, y + 2*h, x + w, y + 3*h - 1); // Окно для красной полосы
textbackground(RED);
clrscr();
}
// NormScreen: восстанавливает нормальное состояние экрана
void NormScreen()
{
window(1, 1, 80, 25); // Окно во весь экран
textbackground(BLACK); // Черный цвет фона
textcolor(LIGHTGRAY); // Светло-серый цвет для символов
clrscr(); // Очистка экрана
}
int main()
{
int h; // Ширина полосы флага
int x = 2, y = 2; // Координаты левого верхнего угла
cout << "Введите размер флага от 1 до 5";
cin >> h;
RussFlag(x, y, h);
getch(); // Ждем нажатия клавиши
NormScreen(); // Восстанавливаем исходные настройки экрана
return 0;
}
Графический режим
В графическом режиме все изображения на экране создаются светящимися точками – пикселями. Разрешающая способность, то есть количество пикселей по горизонтали и по вертикали, зависит от типа монитора и типа электронной схемы (видеоадаптера), обеспечивающей работу монитора.
В состав TC входит библиотека функций для реализации точечной графики, прототипы которых находятся в файле graphics.h.
Графические драйверы и режимы
Для поддержки графического режима работы экрана в оперативную память должна быть загружена специальная программа – графический драйвер. В TC имеются шесть файлов с графическими драйверами: CGA.BGI, EGAVGA.BGI, IBM8514.BGI, HERC.BGI, ATT.BGI, PC3270.BGI. Заметим, что расширениеBGI произошло от слов Borland Graphic Interface. Каждый файл содержит драйвер для одного или нескольких близких по типу видеоадаптеров. Логически TC различает десять графических драйверов. Для каждого драйвера в файле graphics.h определена константа, которую можно считать символическим именем драйвера. Константы графических драйверов, их значения и соответствующие имена файлов перечислены в табл.17.
Таблица 17. Графические драйверы Turbo C++
Константа (символическое имя драйвера) | Значение константы | Имя файла драйвера |
CGA MCGA EGA EGA64 EGAMONO IBM8514 HERCMONO ATT400 VGA PC3270 DETECT | CGA.BGI CGA.BGI EGAVGA.BGI EGAVGA.BGI EGAVGA.BGI IBM8514.BGI HERC.BGI ATT.BGI EGAVGA.BGI PC3270.BGI |
Константа DETECT используется, когда системе самой поручается определить тип видеоадаптера и загрузить соответствующий драйвер. При этом будет использован драйвер, обеспечивающий максимальное разрешение.
Графические драйверы обеспечивают один или несколько различных графических режимов, для которых в файле graphics.h определены константы. В табл.18 приведены имена и значения этих констант для драйвера VGA, разрешение и количество цветов.
Таблица 18. Константы графических режимов
Графический драйвер | Константа графического режима | Значение константы | Разрешение, пикселей | Количество цветов |
VGA | VGALO VGAMED VGAHI | 640 x 200 640 x 350 640 x 480 |
Инициализация графики
Для перевода адаптера экрана в графический режим и загрузки соответствующего драйвера служит библиотечная функция initgraph. Ее прототип имеет вид:
void initgraph(int* GraphDriver, int* GraphMode, char* PathToDriver);
Графический драйвер ищется в каталоге, имя которого указано в аргументе PathToDriver. Если в указанном каталоге драйвер не найден, то просматривается текущий каталог. Если в качестве третьего аргумента указана пустая строка "", то просматривается только текущий каталог. Параметр GraphDriver указывает номер драйвера, GraphMode указывает номер графического режима, который должен быть установлен.
Если положить GraphDriver = 0 или библиотечной константе DETECT, то производится автоматическое распознавание графического адаптера, в память загружается соответствующий драйвер, устанавливается режим с максимальным разрешением, а переменным, указанным в аргументах GraphDriver и GraphMode, присваиваются значения, равные номеру драйвера и номера режима.
Об успехе или неудаче той или иной графической операции можно судить по значению, вырабатываемому функцией:
int graphresult(void);
после каждой графической операции. Результат, равный 0 (значение библиотечной константы grOk), означает удачное, а отрицательное значение – неудачное выполнение операции.
Для восстановления текстового режима служит функция:
void closegraph();
Эта функция освобождает память, выделенную графическому драйверу и выбранному виду шрифта, использовавшегося в графическом режиме.
В графическом режиме каждый пиксель имеет две координаты – по горизонтали и по вертикали экрана. Начало координат находится в левом верхнем углу экрана. Нумерация пикселей начинается с нуля. Направление отсчета: по горизонтали – слева направо, по вертикали – сверху вниз.
Функции рисования
Для рисования на экране имеется довольно много библиотечных функций, объявленных в заголовочном файле graphics.h. Рассмотрим некоторые.
Функция
int getcolor(void);
возвращает текущий цвет рисования. Всего для рисования доступно 16 цветов, они кодируются такими же константами, как в текстовом режиме, табл.16.
Функция
void setcolor(int color);
устанавливает новый цвет рисования color.
Функция
int getbkcolor(void);
возвращает текущий цвет фона.
Функция
void setbkcolor(int color);
устанавливает новый цвет фона color.
Функция
void putpixel(int x, int y, int color);
изображает на экране точку с координатами x, y цветом color.
Функция
void line(int x1, int y1, int x2, int y2);
рисует на экране отрезок прямой, соединяющий точки с координатами (x1, y1) и (x2, y2), используя текущий цвет, текущие стиль и толщину линий. По умолчанию текущим является белый цвет, текущим стилем – сплошная линия, а текущей толщиной – толщина в один пиксель.
Функция
void circle(int x, int y, int Radius);
изображает на экране окружность радиуса Radius с центром, имеющим координаты x, y.
Функции:
int getmaxx(void); int getmaxy(void);
возвращают максимальные координаты точек на экране соответственно в горизонтальном и вертикальном направлениях.
Программа 33. Звезда
На экране рисуется звезда с заданным числом лучей N, вписанная в окружность. Для построения звезды понадобятся некоторые математические вычисления. На рис.29 показана схема экрана, действующая на нем физическая система координат и геометрические построения, необходимые для изображения семиугольной звезды. Показан случай, когда используется драйвер VGA и действует режим работы экрана VGAHI с разрешение 640*480. Максимальная координата пикселя по горизонтальной оси в этом случае будет 639, а по вертикальной 479.
Рис.29. Чертеж для построения звезды
Через xc, yc обозначены координаты центра звезды, R – радиус звезды. Будем нумеровать лучи, начиная с 0. Пусть нулевой луч направлен вверх. Положение лучей можно определять углом fi, отсчитываемым от вертикали. Для i-го луча этот угол будет
.
Из чертежа видно, что координаты первой вершины можно найти по формулам:
.
Координаты i-й вершины рассчитываются по аналогичным формулам, только вместо 1 нужно подставить i.
Когда рассчитаны координаты вершин, построение сводится к соединению их отрезками прямых. Если соединять соседние вершины, получится просто правильный многоугольник. Для семи вершин можно построить два вида звезды, пропуская либо два, либо три отрезка разбиения. Такая возможность в программе реализована с помощью переменной m, задающей число пропускаемых отрезков разбиения.
// Файл Star.cpp
// Программа изображает на экране правильную звезду,
// вписанную в окружность.
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
int main()
{
int Driver, Mode;
int xc, yc; // Координаты центра звезды
const int N = 7; // Количество лучей звезды
int m = 3; // Количество пропускаемых отрезков
const int ColorCircle = YELLOW; // Цвет окружности
const int ColorStar = LIGHTRED; // Цвет звезды
int R = 100; // Радиус окружности
double df = 2 * M_PI / N; // Угол между лучами
double f;
int x[N], y[N]; // Координаты концов лучей
int i;
Driver = DETECT; // Автоматическое определение драйвера
// Инициализация графического режима
initgraph(& Driver, & Mode, "C:\\TC30\\BGI");
if (graphresult() != grOk){ // Если ошибка,
cerr << "Не удалось инициализировать графику \n";
exit(1); // завершить программу
}
xc = getmaxx() / 2; // Координаты
yc = getmaxy() / 2; // центра экрана
for(i = 0; i < N; i++){ // Вычисление координат концов лучей
f = df * i; // Угол i-го луча
x[i] = xc + R * sin(f); // Координаты
y[i] = yc - R * cos(f); // вершины
}
setcolor(ColorCircle); // Установка цвета для окружности
circle(xc, yc, R); // Рисование окружности
setcolor(ColorStar); // Установка цвета для звезды
for(i = 0; i < N; i++) // Рисование лучей
line(x[i], y[i], x[(i + m) % N], y[(i + m) % N]);
getch();
closegraph();
return 0;
}
Обратите внимание на строку "C:\\TC30\\BGI", задающую путь к папке, в которой находятся файлы графических драйверов. В DOS и Windows принято имена вложенных папок отделять обратной наклонной чертой. Для изображения обратной наклонной черты в программе на языке C++, она удваивается.
Координаты вершин звезды хранятся в массивах x и y из N элементов. Для изображения звезды, например, при N=7 и m=3 нужно провести 7 отрезков, соединяющих следующие вершины: 0 и 3, 1 и 4, 2 и 5, 3 и 6, 4 и 0, 5 и 1, 6 и 2. Отрезки рисуются в цикле с помощью функции line. Номера начальных точек i возрастают от 0 до N-1, а номера конечных точек находятся с помощью выражения
(i + m) % N,
где % – оператор нахождения остатка от деления. В правильности данного выражения легко убедиться подстановкой.
Полученное на экране изображение показано на рис.30.
Рис.30. Звезда на экране