Графики, выводимые на экран в текстовом режиме, не отличаются высоким качеством из-за невысокой разрешающей способности экрана в этом режиме. Тем не менее во многих случаях их применение вполне оправдано.
Задача. Написать программу построения графика заданной функции Y=f(X) для аргумента X, изменяющегося от Xmin до Xmax. Для определенности будем считать, что Y=sin(x), Xmin =–2π, Xmax = 2π.
Если известны минимальное и максимальное значение функции, то областью, в которой располагается реальный (натурный) график, является прямоугольник с координатами (при общепринятом направлении осей):
левый верхний угол – (Xmin, Ymax);
правый нижний угол – (Xmax, Ymin).
На экране для размещения графика тоже должна быть выделена прямоугольная область, координатами которой (с учетом выбранного направления оси Y вниз) будут:
левый верхний угол – (xGmin, yGmin);
правый нижний угол – (xGmax, yGmax),
здесь обозначено:
xGmin – x графическое минимальное,
xGmax – x графическое максимальное,
yGmin – y графическое минимальное,
yGmax –y графическое максимальное.
В общем случае "область реального существования" функции должна быть отражена на "область ее экранного существования". Для этого должны быть вычислены масштабы – коэффициенты, с помощью которых натурные величины (X, Y) будут переводиться в графические координаты (xG, yG).
Масштабы можно определить по следующим формулам:
Mx := (xGmax-xGmin)/(Xmax-Xmin); { Масштаб по X }
My := (yGmax-yGmin)/(Ymax-Ymin); { Масштаб по Y }
которые получены из условия, что стороны "экранного" прямоугольника точно будут соответствовать сторонам "реального" прямоугольника.
Максимальное и минимальное значения функции (хотя бы приблизительные, лучше с запасом в большую по абсолютной величине сторону) должны быть определены пользователем.
Для перехода к графическим координатам получим следующие соотношения:
xG:=xGmin+Round((x-Xmin)*mx);
yG:=yGmin+Round((Ymax-y)*my);
Здесь функция Round(аргумент) используется для получения целого значения с правильным округлением, а "несимметричность" ее аргумента вызвана тем, что на экране ось Y направлена вниз.
Используя эти формулы, можно провести оси X и Y на графике: оси X соответствует y=0 во второй формуле, а оси Y – x=0 в первой формуле. Аналогично, можно легко нанести на график сетку линий: для горизонтальных линий задают необходимые значения Y во второй формуле, а для вертикальных – значения X в первой.
Приводимая ниже программа не является универсальной, но она демонстрирует приемы, которые могут быть использованы при написании более качественных продуктов.
Для проведения горизонтальных и вертикальных линий в программе используются процедуры, для вычисления заданной зависимости используется функция. Все необходимые действия выполняются последовательно и автономно. При необходимости любое количество используемых констант может быть заменено переменными, значения которых будут запрашиваться у пользователя в режиме диалога. В операторах While условие окончания записано так, чтобы гарантированно выводилась последняя линия или точка. Обратите внимание, что если назначены пределы изменения по оси X на экране (xGmin, xGmax), то количество точек на этой оси будет (xGmax–xGmin+1), и количество интервалов (шагов) нет смысла назначать более (xGmax–xGmin). Константы, определяющие размеры графика на экране (xGmin, xGmax, yGmin, yGmax), назначены с учетом возможности сделать необходимые надписи вне поля графика.
Program PlotGraf;
uses
crt;
const
Xmin=-pi; { Начальное и }
Xmax= pi; { конечное значения аргумента}
xGmin=5; { Начальное и }
xGmax=75; {конечное значение координат экрана по оси X}
Ymin=-1; { Минимальное и }
Ymax=1; {максимальное значения функции (предполагаемое)}
yGmin=5; { Начальное и }
yGmax=45; {конечное значение координат экрана по оси Y}
kgl=11; { Количество проводимых горизонтальных и }
kvl=11; { вертикальных линий }
kix=xGmax-xGmin; { Количество интервалов по оси X }
var
x, y, { Текущие значения X и Y }
mx, my, { Масштабы по X и Y }
hx, hy : real; { Шаги по X и Y }
xg, yg : integer; {Значения графических координат X и Y}
Function myFunc(x:real):real;
begin
myFunc:=sin(x); { Функция для построения графика }
end; { myFunc }
Procedure ver_Line(x,yn,yk:integer; sim:char);
{ Строит вертикальную линию, проходящую через X }
{ от yn до yk, используя символ sim }
var
y : integer;
Begin
For y:= yn to yk do
begin
GoToXY(x,y);
Write(sim);
end;
End; { ver_line }
Procedure Gor_Line(y,xn,xk:integer; sim:char);
{ Строит горизонтальную линию, проходящую через Y }
{ от xn до xk, используя символ sim }
var
x: integer;
Begin
GoToXY(xn,y);
For x:= xn to xk do
Write(sim);
End; { Gor_line }
begin
TextMode(c80+256); { Цветной режим с 50 строками }
TextBackGround(White);
ClrScr; { Фон - белый }
mx:=(xgmax-xgmin)/(xmax-xmin); { Масштаб по X }
my:=(ygmax-ygmin)/(ymax-ymin); { Масштаб по Y }
{ Проведение горизонтальных линий }
y:=ymin;
hy:=(ymax-ymin)/(kgl-1); { Шаг между линиями }
TextColor(Yellow); {Желтый цвет горизонтальных линий }
while y<=ymax+0.1*hy do
begin
yg:=ygmin+Round((ymax-y)*my);{Графическая координата по Y}
Gor_Line(yg,xgmin,xgmax,’-’);
GoToXY(xgmin-4,yg); { Курсор в нужное место и }
write(y:4:2); { вывод значения около линии }
y:=y+hy; { Очередное значение Y }
end;
{ Проведение оси X (на ней y=0) }
yg:=ygmin+Round(ymax*my); {Графическая координата по Y}
TextColor(Blue);
Gor_Line(yg,xgmin,xgmax,'-');
Write(’->X’); { Вывод обозначения оси X }
{ Проведение вертикальных линий }
x:=xmin;
hx:=(xmax-xmin)/(kvl-1); { Шаг между линиями }
TextColor(Red); { Зеленый цвет горизонтальных линий }
while x<=xmax+0.1*hx do
begin
xg:=xgmin+Round((x-xmin)*mx);
Ver_Line(xg,ygmin,ygmax,’:’);
GoToXY(xg-2,ygmin-2); {Курсор в нужное место и }
write(x:4:2); {вывод значения около линии }
x:=x+hx; { Очередное значение Y }
end;
{ Проведение оси Y (на ней x=0) }
xg:=xgmin-Round(xmin*mx); {Графическая координата по X}
TextColor(Blue);
Ver_Line(xg,ygmin,ygmax,’!’);
GoToXY(xg,ygmin-1); { Курсор в нужное место и }
Write(’^Y’); { вывод обозначения оси Y }
{ Построение графика }
x:=xmin;
hx:=(xmax-xmin)/kix; { Шаг по X }
while x<=xmax+0.1*hy do
begin
xg:=xgmin+Round((x-xmin)*mx);{Графическая координата по X}
y:=myFunc(x); { Вычисление y }
yg:=ygmin+Round((ymax-y)*my);{Графическая координата по Y}
GoToXY(xg,yg); { Курсор в нужное место }
TextColor(Black);
Write(’*’); { Вывод точки графика }
x:=x+hx;
end;
GoToXy(10,48);
Write(’Нажмите любую клавишу...’);
Repeat Until KeyPressed;
end.
Процедуры задания цвета фона и текста широко используются для представления различных меню. Рассмотрим пример программы, которая реализует меню с использованием средств модуля Crt.
23.1.5. Алгоритм и программа представления меню средствами Турбо Паскаля
Реализация меню предполагает выполнение следующих операций:
1) вывод пунктов меню основной парой цветов (фона и текста);
2) вывод выбранного пункта меню другой парой цветов (более яркой);
3) передвижение по меню с помощью традиционных управляющих клавиш;
4) выбор пункта меню для выполнения соответствующей операции;
5) выход из меню.
Три последние операции выполняются с использованием управляющих клавиш, которые имеют следующие коды:
#13– Enter;
#27 – Esc;
#77 – перемещение курсора влево;
#75 – перемещение курсора вправо;
#72 – перемещение курсора вверх;
#80 – перемещение курсора вниз.
Первым двум кодам соответствует один байт (символ), а остальным – два, причем первый байт у них имеет нулевой код.
Рассмотрим алгоритм и программу на примере горизонтального меню, содержащего не более 5 пунктов. Выбор пункта осуществляется нажатием клавиши Enter, а выход из него и из программы – нажатием клавиши Esc. После выбора пункта для простоты выдается сообщение о том, что он выполняется. Названия пунктов соответствуют названиям операций.