Uploaded by Виталий Сычевский

ИССЛЕДОВАНИЕ ВИДЕОСИСТЕМЫ (ГРАФИЧЕСКИЙ РЕЖИМ)

advertisement
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра ВТ
ОТЧЕТ
по лабораторной работе №3
по дисциплине «Организация ЭВМ и систем»
Тема: ИССЛЕДОВАНИЕ ВИДЕОСИСТЕМЫ (ГРАФИЧЕСКИЙ РЕЖИМ)
Студент гр. 8005
Преподаватель
Павлов С.М.
Санкт-Петербург
2021
Цель работы - изучение работы с видеосистемой в графическом режиме,
вывод графика заданной функции с масштабированием и разметкой осей.
Краткие сведения о видеосистемах ПЭВМ.
Основным техническим средством для оперативного формирования и
отображения как текстовой, так и графической информации в компьютере
является видеосистема.
Видеосистема компьютера состоит из трех основных компонентов:

видеоадаптер (видеокарты);

монитор (дисплей);

программное обеспечение (драйверы видеосистемы).
Видеоадаптер посылает в монитор сигналы управления яркостью лучей и
синхросигналы строчной и кадровой развёрток. Монитор преобразует эти
сигналы в зрительные образы. А программные средства обрабатывают
видеоизображения — выполняют кодирование и декодирование сигналов,
координатные преобразования, сжатие изображений и др.
Графический режим работы видеосистемы.
Графический режим монитора предназначен для вывода на экран графиков,
рисунков и т. д. Разумеется, в этом режиме можно выводить также и текстовую
информацию в виде различных надписей, причем эти надписи могут иметь
произвольный шрифт, размер букв и т.д. В графическом режиме экран
монитора состоит из точек, каждая из которых может быть одного из
нескольких цветов. Количество точек по горизонтали и вертикали называется
разрешающей способностью монитора в данном режиме. Например, выражение
разрешающая способность 640 x 200 - означает, что монитор в данном режиме
выводит 640 точек по горизонтали и 200 точек по вертикали.
2
Принцип работы с графической библиотекой.
Прежде чем использовать функции графической библиотеки С++, необходимо
инициализировать систему графики - загрузить соответствующий адаптеру или
режиму .BGI-драйвер, установить в начальные значения внешние переменные и
константы, выбрать шрифт и т.д. Начнем рассмотрение с подключения
графического режима:
int driver, mode; // драйвер и режим
driver = DETECT;
// автоопределение
initgraph(&driver,&mode,"c:\\borlandc\\bgi");
Инициализацию графической модели выполняет функция initgraph():
void far initgraph(int *graphdriver, int *graphmode, char * pathtodriver).
При вызове она инициализирует графическую систему, загружая. BGIдрайвер, определяемый указателем graphdriver, и устанавливая видеоадаптер в
графический режим, задаваемый указателем graphmode. Третий аргумент
функции initgraph() задает маршрут поиска файла, содержащего .BGI-драйвер.
Если файл не найден в заданной директории, функция просматривает текущий
директорий.
В
нашем
случае
маршрут
задан
следующим
образом:
"c:\\borlandc\\bgi"
С++ поддерживает фиксированное число драйверов, каждый из которых, в
свою очередь, поддерживает ряд режимов. Как тип драйвера, так и режим могут
быть заданы числом или символической константой.
Далее перейдем непосредственно к выводу графика заданной функции:
Две функции позволяют определить ширину и высоту экрана в пикселах для
текущего видеорежима: getmaxx() и getmaxy().
Задание стиля линии выполняет функция setlinestyle().
void setlinestyle (int linestyle, unsigned upattern, int thickness) - устанавливает
стиль "рисования" отрезков прямых линий и графических примитивов.
Аргумент linestyle выбирает стиль линии, а аргумент thickness - толщину линии.
3
Аргумент upattern используется только в том случае, когда задается
отличный от предопределенных стиль линии, т.е. если linestyle равен
USERBIT_LINE (4).
Что же касается функции rectangle(), то ее прототип выглядит следующим
образом:
void rectangle( int left, int top, int right, int bottom) - выводит контур
прямоугольника, заданного координатами левого верхнего (left, top) и правого
нижнего (right, bottom) углов. Координаты углов задаются относительно
координат левого верхнего угла текущего графического окна. Контур
выводится линией текущего цвета и стиля. Цвет контура устанавливается
функцией setcolor(). Стиль линии задается функцией setlinestyle().
Заполнение цветом прямоугольной области выполняется с помощью
функций setfillstyle и floodfill.
Начнем с setfillstyle():
void setfillstyle(int pattern, int color) - выбирает один из предопределенных
стилей заполнения. Значение pattern идентифицирует стиль. Аргумент color
задает цвет, используемый для пикселов по заданному шаблону.
Задав стиль, перейдем к самому заполнению, выполняемому функцией
floodfill():
void floodfill (int x, int y, int border) - заполняет текущим стилем область экрана,
ограниченную непрерывной линией с цветом border, начиная с точки с
координатами (х, у). Функция заполняет область либо внутри замкнутой линии,
либо вне ее. Это зависит от положения начальной точки: если она лежит внутри
области, заполняется внутренняя область; если точка лежит вне замкнутой
области, заполняется внешняя область; если точка лежит точно на линии цвета
border, заполнение не производится. Заполнение начинается с начальной точки
и продолжается во всех направлениях, пока не встретится пиксел с цветом
border. Цвет border должен отличаться от цвета заполнения, в противном случае
будет заполнен весь экран.
4
Построение графика функции выполняется с помощью функции drawf():
На вход подаем количество точек по оси X, для которых будет рассчитано
значение функции.
Переменная dx отвечает за шаг аргумента x, шаг рассчитывается в
соответствии с диапазоном аргумента, представленном в задании. Далее создан
цикл, осуществляющий поиск максимума значения функции на представленном
диапазоне аргумента x. После того, как максимум найден запускаем цикл
отрисовки заданной функции: рассчитываем значение в каждой точке
диапазона, и устанавливаем найденную точку на экран с помощью функции
putpixel():
void putpixel(int x, int у, int pixelcolor)
Определяет, лежит ли пиксел с координатами (х, у) в текущем графическом
окне, и, если лежит, выводит на экран пиксел, код цвета которого равен
pixelcolor. В противном случае цвет пиксела не изменяется. Используя
функцию putpixel(), можно "стереть" пиксел, если вывести его с кодом цвета
фона. Для того, чтобы пиксел лежал в созданном окне необходимо нормировать
координату значения функции, привести ее к целочисленному значению, а
потом привести эту координату к соответствующим параметрами окна.
Нарисовав график функции, перейдем к отрисовке координатных осей:
За стиль координатных осей отвечает функция setlinestyle(), описанная
выше. Чтобы нарисовать оси, необходимо воспользоваться функцией line():
void line( int x1, int y1, int x2, int y2) - выводит отрезок прямой линии между
двумя явно специфицированными точками (x1, y1) и (х2, у2), используя
текущие цвет, стиль, толщину и режим вывода линии. Координаты (x1, y1) и
(х2, у2) задаются относительно левого верхнего угла текущего графического
окна. Функция не изменяет текущую позицию.
Подпись осей выполняется функцией outtextxy():
void outtextxy (int x, int y, char *textstring) - выводит ASCII-строку текста, на
начало которой указывает textstring, используя текущие цвет, установки
направления, типа шрифта и выравнивания строки. Аргументы х и у явно
5
специфицируют новую текущую позицию, используемую для вывода строки.
Координаты X и Y измеряются относительно координат левого верхнего угла
текущего графического окна.
Для разметки осей создает циклы, следующего вида:
for(i=0; i<29; ++i)
line(X0+20*i,Y0-220,X0+20*i,Y0-225);
В таких циклах отрисовываем штрихи, находящиеся друг от друга на
определенном расстоянии, как это реализовано на обычной линейке.
Подписываем штрихи с помощью outtextxy().
После построения графика и координатных осей, осталось вывести
максимальное значение функции на заданном диапазоне значений аргумента.
Максимальное значение находили в функции drawf() описанной выше.
Это значение было найдено в формате float, для того чтобы вывести его была
создана следующая конструкция:
Вначале используем функцию sprintf(), чтобы записать максимальное
значение в массив символов:
int sprintf(char *buf, const char *format, arg-list)
Функция sprintf() идентична printf(), за исключением того, что вывод
производится в массив, указанный аргументом buf.
Далее создав еще один массив (который будет содержать текст надписи,
выводимой впоследствии на экран), добавим в него текст с помощью функции
strcpy():
char *strcpy(char *str1, const char *str2)
Функция strcpy() используется для копирования содержимого str2 в str1.
Аргумент str2 должен быть указателем на строку, оканчивающуюся нулем.
Функция strcpy() возвращает указатель на str1. Если строки str1 и str2
перекрываются, то поведение функции strcpy() не определено.
Теперь “соединим” массивы с значением максимума функции и с
надписью о том, что это максимальное значение. Эту операцию выполнит
функция strcat():
6
char *strcat(char *str1, const char *str2)
Функция strcat() конкатенирует (соединяет в цепочку) строку str1 и копию
строки str2. В конце модифицированной строки str1 функция устанавливает
нулевой символ. Нулевой символ, первоначально завершавший строку str1,
замещается
первым
символом
строки
str2.
Строка
str2
остается
в
первоначальном виде.
Для того, чтобы эти функции работали подключаем библиотеки string.h и
stdio.h. Вывод максимального значения непосредственно на экран осуществляет
уже известная ранее функция outtextxy().
Т.к. функции графической библиотеки больше не нужны, следует вызвать
функцию closegraph() "закрытия" графического режима и возвращения к
текстовому режиму.
Эта функция освобождает память, распределенную под драйверы графики,
файлы шрифтов и промежуточные данные и восстанавливает режим работы
адаптера в то состояние, в котором он
находился
до
выполнения
инициализации системы.
Задание.
1. Разработать программу для вывода на экран графика
Sin2(x/2)+Sqrt(x) с диапазоном от 3π/2 до 15π.
2. Произвести разметку осей.
3. Найти максимальное значение функции на заданном интервале.
Текст программы.
#include "iostream"
#include "stdio.h"
#include "conio.h"
#include "math.h"
#include "dos.h"
#include "graphics.h"
#include "string.h"
using namespace std;
int Xmax, Ymax, X0, X1, Y0, Y1;
float R, MaxF=0.;
7
функции
void Foo(int N)
{
double x=3*3.14/2, dx=(15*3.14-(3*3.14)/2)/N;
MaxF=(float)(pow((sin(x/2)),2.0)+sqrt(x));
for(int i=0;i<N;i++)
{
double z = x + i * dx;
R = (float)(pow((sin(z/2)),2.0)+sqrt(z));
if(MaxF < R)
{
MaxF = R;
}
}
for (int i=0; i<N; i++, x+=dx)
{
R=(float)(pow((sin(x/2)),2.0)+sqrt(x));
putpixel(i+X0+20,(Y0-(int)(R/MaxF*(float)(Y0-Y1)))/2-5,GREEN);
}
}
int main()
{
int i, N;
int driver, mode;
driver = DETECT;
initgraph(&driver,&mode,"c:\\borlandc\\bgi");
Xmax=getmaxx();
Ymax=getmaxy();
X0=20;
Y0=Ymax-30;
X1=Xmax-30;
Y1=30;
N = X1-X0;
Foo(N);
setlinestyle(0,1,1);
line(X0+20, Y0-5, X0+20, Y1-20);
line(X0+20, Y0-220, X1+20, Y0-220);
outtextxy(Xmax/4,Y0-100,"sin^2(x/2)+sqrt(x)");
outtextxy(X1+3,Y0-219,"x");
for(i=1;i<23;++i)
line(X0+20,Y0-i*20,X0+25,Y0-i*20);
for(i=0;i<29;++i)
line(X0+20+20*i,Y0-220,X0+20+20*i,Y0-225);
outtextxy(X0+23,Y0-218,"1.5");
outtextxy(X0+20*5,Y0-218,"3.5");
outtextxy(X0+20*9,Y0-218,"5.5");
8
outtextxy(X0+20*13,Y0-218,"7.5");
outtextxy(X0+20*17,Y0-218,"9.5");
outtextxy(X0+20*21,Y0-218,"11.5");
outtextxy(X0+20*25,Y0-218,"13.5");
char cMaxF[10];
sprintf(cMaxF,"%f",MaxF);
char str[24];
strcpy(str,"MAX(f(x)) = ");
strcat(str,cMaxF);
outtextxy(Xmax/4,Y0-60,str);
getch();
closegraph();
}
Пример запуска программы.
9
Структурная схема аппаратных средств.
Центральный
процессор
Оперативная
память
ЦП
ОЗУ
Графический
монитор
Информационная магистраль
Видеоконтроллер
Видеопамять
Графический
процессор
Видеоадаптер
10
Download