Лабы / Создание программ построения графиков(лаб1)
.docМосковский Государственный институт электронной техники
(Технический университет)
Кафедра "Информатика и ПО ВС" Курс:
"Интерактивные графические системы"
УТВЕРЖДАЮ:
Завкафедрой ИПОВС
д.т.н. профессор В.Ф.Шаньгин
1993г.
ЛАБОРАТОРНАЯ РАБОТА
СОЗДАНИЕ ПРОГРАММ ПОСТРОЕНИЯ ГРАФИКОВ, ГИСТОГРАММ И КРУГОВЫХ ДИАГРАММ
Составила:
асс.Соколова Н.Ю.
Москва - 1993г.
Лабораторная работа
Создание программ построения графиков, гистограмм, круговых диаграмм
Цель работы:
1) Изучить возможности Турбо-Паскаля для получения графической информации
2) Получить навыки программирования графиков функции столбчатых диаграмм
(гистограмм) и круговых диаграмм
Аппаратура: IBM PC.
Введение
Одним из основных достоинств машинной графики является возможность нагляд-
ного представления информации. Это свойство широко используется в инженерной
практике при отображении результатов различных расчетов. При проведении рас-
четов над данными, представленными в табличной форме, широкое распростране-
ние, благодаря своей универсальности и простоте, получили пакеты прикладных
программ для работы с электронными таблицами. Электронная таблица является и
универсальным средством для автоматизации расчетов над табличными данными.
Наиболее известной электронной таблицей является пакет прикладных программ
Суперкалк (SuperCalc), имеющий несколько версий. Электронная таблица
SuperCalo фирмы Computer
Associates включает в себя СУБД, текстовый редактор, подсистему машинной
графики. Подсистема графики позволяет строить диаграммы с использованием раз-
личных цветовых палитр. SuperCalc обеспечивает работу с диаграммами семи раз-
личных типов: круговая диаграмма, столбиковая диаграмма, линейная диаграмма,
диаграмма Х-У, диаграмма площадей, интервальная диаграмма. Кроме основных
элементов, характеризующих числовые данные электронной таблицы, каждая диаг-
рамма может включать оформительские элементы, улучшающие ее внешний вид и ин-
формативность. Данные, представленные в виде графиков, гистограмм, диаграмм,
намного легче анализировать, чем те же данные представленные табличным обра-
зом.
Построение графика функции
Для построения графика функции необходимо иметь таблицу (массив) значений
аргумента и таблицу соответствующих значений функции. Каждой паре чисел из
этих таблиц на графике будет соответствовать точка. Высветив все точки графи-
ка, получим совокупность точек - точечный график. На практике мы привыкли
иметь дело с графиками, изображенными в виде непрерывной кривой (для непре-
рывной функции).
Поэтому мало высветить отдельные точки графика, требуется их соединить кри-
вой. Для этого можно использовать различные методы аппроксимации. Здесь расс-
матривается кусочно-линейная аппроксимация, при которой отдельные точки гра-
фика соединяются отрезками прямых. В результате вычерчивание кривой сводится
к рисованию отдельных отрезков, аппроксимирующих кривую. При малом шаге изме-
нения аргумента кусочно-линейная аппроксимация дает хорошее приближение кри-
вой.
При отображении точек графика на экране дисплея необходимо перейти от физи-
ческих величин, в которых измеряются значения аргумента и функции к безмерным
величинам - координатам точек растра экрана, т.е. сопоставить каждой точке
реального графика (в мировых координатах) точку на экране дисплея (в коорди-
натах устройства). Эта операция называется масштабированием.
При вычерчивании графика нельзя ограничиться изображением только кривой
графика. Требуется провести координатные оси, произвести их разметку (надпи-
сать), а также при необходимости нанести координатную сетку, состоящую из
прямых, параллельных координатным осям и проводимых с определенным шагом по
горизонтали и вертикали.
Рассмотрим поочередно решение каждой из поставленных задач. При проведении
масштабирования учтем, что для наглядности восприятия ось абсцисс будет нап-
равлена слева направо, а ось ординат - снизу вверх.
Следует также учесть, что график будет располагаться в пределах поля выво-
да, размеры которого несколько меньше размеров всего экрана. Это связано с
тем, что необходимо вывести сверху название графика (поясняющий текст), а
слева и внизу вывести числовые значения откладываемых величин.
Поле вывода графика можно задать, указав координаты (Xn, Yn) левого верхне-
го угла поля вывода и координаты (Xk, Yk) правого нижнего угла. Тогда диапа-
зону изменения аргумента Хmах - Xmin будет соответствовать диапазон измене-
ния координат экрана Xk - Xn, а диапазону изменения значений функции Уmах -
Ymin - диапазон экранных координат Yk - Yn.
Масштаб по каждой из осей можно определить из следующего выражения:
DX
m = --------- ,
DZ
где m - масштаб;
DN = МАХК - MINK - диапазон номеров позиций - разность максимальной и мини-
мальной координат поля вывода графика;
DZ = МАХW - MINW - диапазон значений величины, выводимой в виде графика
(для аргумента и функции) - разность максимальной и минимальной величин.
Масштаб показывает, скольким точкам растра на экране соответствует единица
физической величины. Для определения позиции экрана для очередной точки гра-
фика следует воспользоваться следующими формулами:
а) для оси абсцисс
Х - Xmin
КХ = ](Х - Xmin) * m [+ Хп=]------------- * (Xk - Хn)[+ Хn (1)
Хmах - Xmin
где КХ - номер позиции в строке (вдоль оси абсцисс);
Х - текущее значение аргумента функции;
Xmin - минимальное значение аргумента;
Xmax - максимальное значение аргумента;
][ - округление до ближайшего целого.
б) для оси ординат:
(Ymax - Y) *(Yk - Yn)
KY = ](Ymax - Y) * m[ + Yn =]----------------------- [+ Yn (2)
Ymax - Ymin
Эти выражения позволяют определить координаты точек графика, соединив кото-
рые отрезками прямых, получим кривую (точнее ломаную линию) графика.
Знаменатели в этих выражениях могут равняться нулю. В (1) это будет, если
Xmin = Хmах, т.е. имеем всего одно значение аргумента и, следовательно, одну
точку, т.е. кривой графика нет. Такой случай можно рассматривать как некор-
ректные исходные данные и при необходимости вставить в программу анализ ситу-
ации с выдачей соответствующего сообщения.
Иначе обстоит дело во втором случае, когда Ymin = Ymax. График функции
представляет собой горизонтальную прямую. Если заранее известно, что значение
функции на заданном интервале изменения аргумента не изменяется, то и рисо-
вать график смысла нет. Однако это не всегда можно предвидеть заранее: выво-
дится график неизученной функции более подробно (в большем масштабе) рассмат-
ривается какой-то участок с целью как раз убедиться в характере изменения
кривой. Втретьих, ситуация, когда Ymin = Ymax, может возникнуть, если значе-
ния функции изменяются столь незначительно, что ограничения разрядной сетки
ЭВМ не позволяют этого заметить.
Если график функции представляет собой горизонтальную прямую, то ее можно
провести на любом расстоянии от нижней или верхней границы поля вывода. В
программу следует заложить выполнение следующего алгоритма
(при Ymax = Ymin):
при Ymax > 0 положить Ymax = 2 * Ymax, Ymin = 0;
при Ymax < 0 положить Ymax = 0, Ymin = 2 * Ymin.
Рассмотрим вторую задачу - нанесение сетки и надписей. Обычно при нанесении
сетки задается количество интервалов, на которые разбивается поле вывода
вдоль оси Х (обозначим его через ndy).
Разность значений аргумента и функции, соответствующая интервалу между дву-
мя линиями сетки, определяется выражениями:
Хmах - Xmin
dx =------------- ( 3 )
ndx
Ушах - Yrnin
dy = ------------- ( 4 )
ndy
где dx - разность значений аргумента;
dy - разность значений функции;
ndx - количество интервалов на которое разбивается поле вывода вдоль
оси X;
ndy - количество интервалов на которое разбивается поле вывода вдоль
оси Y.
Расстояние между линиями сетки, выраженные в координатах устройства, опре-
деляются из формул ( 5 ) и ( 6 ):
Xk - Xn
lx = ] ---------- [ ( 5 )
ndx
Yk - Yn
ly = ] ---------- [ ( 6 )
ndy
где lx - расстояние между вертикальными линиями сетки;
ly - расстояние между горизонтальными линиями сетки.
При нанесении вертикальных линий абсциссы этих линий изменяются от Xn до Xk
с шагом lx, а ординаты имеют значения Yn и Yk.
При нанесении горизонтальных линий ординаты этих линий изменяются от Yn до
Yk с шагом ly, а абсциссы имеют значения Xn и Xk.
Надписи выводим вдоль оси абсцисс и ординат рядом с соответствующей линией
сетки.
Выведем надписи вдоль оси абсцисс. Необходимо вывести числовое значение
Xmin, через lx точек (против вертикальной линии сетки) - Xmin + dx и т.д.
вплоть до конца оси X.
Если n - общее количество позиций в записи числа, а m - количество позиций
в дробной части, то абсцисса первой записи определится из выражения:
Xn + lx *(i - 1) - (n - m) * 8 + 4 ( 7 )
где i - номер записи.
В этом случае точка в записи числа окажется напротив линии сетки. В выраже-
нии (7) учтено, что каждый символ при выводе на экран занимает прямоугольник
размером 8*8 точек. Тогда начало записи надо сместить на (n - m - 1) * 8 + 4
точек влево, где n - m - 1 - количество позиций в записи числа до точки, а 4
- половина прямоугольника для высвечивания точки (если считать, что точка
высвечивается посередине прямоугольника).
Выводим надписи и вдоль оси ординат. Абсцисса начальной точки вывода надпи-
си определяется выражением
Хn - n * 8 - 15, ( 8 )
где n - количество позиций в записи числа;
15 - интервал между записью и осью Y.
Ордината начальной точки вывода записи определяется из выражения
Yn + ly * (i-1) - 4 ( 9 )
где 4 - смещение, введенное для того, чтобы линия сетки оказывалась посере-
дине (в вертикальном направлении) записи.
Переход от действительной формы представления констант к их строковому
представлению осуществляется стандартной функцией Str.
Пример программы построения графика функции
f(x) = sin(2x) + cos(x).
Unit Graphik; { Построение графика функции }
Interface
uses Graph, Crt;
const k=101; xn=100; xk=620; yn=70; yk=-320; ndx=10; ndy=10; n=5; m=2;
strl='График функции f(x)=sin(2x)+cos(x)';
var
i,driver,mode,lx,ly,mx,my:integer;
kx:array[1..k] of integer;
ky:array[1..k] of integer;
x:array[1..k] of real;
y:array[1..k] of real;
dx,dy,rx,ry,ymin,ymax,xmin,xmax:real;
st:string;
function f(x:real):real;
procedure graphfun;
Implementation
{Подпрограмма для вычисления значений заданной функции}
function f(x:real):real;
begin
f:=sin(2*x)+cos(x);
end;
procedure graphfun;
begin
Textbackground(red);
clrscr;
Window(10,8,35,16);
Textbackground(blue);
Clrscr;
TextColor(Magenta);
{ввод исходных данных}
GOTOXY(2,2);
Write ('максимальное значение');
GotoXY(10,4); Readin (Xmax);
{ввод исходных данных}
Window(40,8,65,16);
Textbackground(blue);
Clrscr;
TextColor(Magenta);
GotoXY(2,2);
Write ('минимальное значение');
GotoXY(10, 4);
Readin (Xmin);
{инициализация графического режима}
driver:=detect;
InitGraph(driver,mode,'c:\t_pascal\bgi');
SetBkColor(blue);
SetColor(yellow);
dx:=(xmax-xmin)/(k-1);
{шаг изменения аргумента}
{вычисление таблицы значений аргумента и функции}
{поиск минимума и максимума}
уmin:=1.0е10;
уmaх:=-1.0е10;
for i:=1 to k do
begin
x[i]:=xmin+(i-1)*dx;
y[i]:=f(x[i]);
if y[i] < ymin then ymin:=y[i];
if y[i] > ymax then ymax:=y[i];
end;
if ymin=ymax then
begin
if ymax > 0 then
begin
уmах:=2*ymax;
ymin:=0;
end else
begin
ymax:=0;
ymin:=2*ymin;
end;
end;
rx:=x[k]-x[1]; {диапазон изменения аргумента}
ry:=ymax-ymin; {диапазон изменения функции}
mx:=xk-xn; {ширина поля вывода}
my:=yk-yn; {высота поля вывода}
{определение координат точек графика}
for i:=1 to k do
begin
if rx=0 then kx[i]:=xn+mx div 2
else kx[i]:=round((x[i]-x[1])*mх/rх)+хn;
ky[i]:=round((ymax-y[i])*my/ry)+yn;
end;
OutTextXY(xn, yn-50, str1);
{построение кривой графика}
SetLineStyle(0,0,3); {рисование кривой утолщенной линией}
for i:=1 to k-1 do
Line (kx[i],ky[i],kx[i+1],ky[i+1]);
{нанесение вертикальных линий сетки и вывод надписей вдоль оси абс-
цисс}
SetLineStyle(0,0,1);
lx:=(xk-xn) div ndx;
dx:=(x[k]-x[1])/ndx;
if rx=0 then {одно значение аргумента и функции}
begin
Setcolor(Magenta);
Line(xn,yn,xn,yk);
Line(xk,yk,xk,yn);
Str(xmin:n:m,st);
SetColor(LightGray);
OutTextXY(xn+mx div 2-(n-m)*8+4,yk+15, st);
end
else { несколько значений аргумента и функции }
for i:=1 to ndx+1 do
begin
SetColor(Magenta);
Line(xn+lx*(i-1),yn,xn+lx*(i-1),yk);
SetColor(LightGray);
Str((xmin+(i-1)*dx):n:m,st);
OutTextXY(xn+lx>(i-1)-(n-m)*8+4,yk+15,st);
end;
{нанесение горизонтальных линий сетки и вывод надписей вдоль оси
ординат}
ly:=(yk-yn) div ndy;
dy:=(ymax-ymin)/ndy;
for i:=1 to ndy+1 do
begin
SetColor(Magenta);
Line(xn,yn+(i-1)*ly,xk,yn+(i-1)*ly);
Str((ymax-(i-1)*dy):n:m,st);
SetColor(LightGray);
OutTextXY(xn-(n*8+15),yn+(i-1)*ly-4,st);
end;
SetColor(Brown);
OutTextXY(300,450,' Нажмите Enter > ');
readln;
CloseGraph;
end;
end.
Построение гистограмм
Гистограмма, или столбчатая диаграмма, является часто встречающейся формой
представления информации. Гистограмма представляет собой совокупность смежных
прямоугольников (столбиков), построенных из одной прямой линии. Высота каждо-
го прямоугольника пропорциональна величине отображаемой функции. Гистограммы
обычно используют для представления каких-то статистических данных, например,
количества осадков, выпавших в каждом месяце года; количества резисторов с
фиксированным отклонением от заданного номинала в определенной партии.
При построении гистограммы в качестве исходных данных обычно задается мас-
сив значений некоторой величины (функции), который надо представить в виде
столбчатой диаграммы. Приступая к составлению программы, необходимо опреде-
лить поле вывода для построения гистограммы и в соответствии с его размерами
провести масштабирование.
Масштабирование вдоль оси абсцисс будет заключаться по сути дела в выборе
ширины прямоугольников и определении координат левого нижнего угла каждого
прямоугольника гистограммы. Здесь и заключено отличие гистограммы от графика:
если на графике значение функции отображается в виде точки, то на гистограмме
- в виде прямоугольника. Следует иметь ввиду, что при большом количестве пря-
моугольников их ширина может быть достаточно малой и наглядность представле-
ния информации будет сведена на нет. Прямоугольники гистограммы могут изобра-
жаться как вплотную друг к другу, так и с некоторым промежутком.
Столбцы гистограммы изображаются обычно шире промежутка между ними, т.к.
узкие столбцы менее наглядны.
Зададим промежуток между прямоугольниками в долях от ширины прямоугольника.
Абсциссу левого нижнего угла каждого прямоугольника можно определить из выра-
жения:
DN
KX(i)=]-------------- * (1+ X)>(i-1)[ + KMIN (10)
N + (N-1) * X
где KX(i) - номер позиции в строке левого угла i-го прямоугольника,i=1,N;
N - количество изображаемых прямоугольников;
DN - ширина поля вывода гистограммы - разность абсцисс правой крайней и
левой крайней точек;
Х - отношение ширины промежутка между прямоугольниками к ширине самого
прямоугольника;
KMIN - номер позиции в строке левой крайней точки поля вывода гистог-
раммы.
Масштаб по оси ординат рассчитывается исходя из того, что высота прямоу-
гольника пропорциональна значению функции. При этом основание прямоугольника
всегда лежит на нулевой линии (линия, соответствующая нулевому значению функ-
ции).
Ордината вершины прямоугольника гистограммы определяется из выражения (11):
Y(i) * DN
KY(i) = KY0 - ----------- ( 11 )
Ymax - Ymin
где KY0 - номер позиции в столбце, соответствующей нулевой линии гистограм-
мы.
KY(i) - номер позиции в столбце вершины i-го прямоугольника;
Y(i) - i-oe значение функции;
DN - высота поля вывода гистограммы - разность максимальной и минималь-
ной ординат поля вывода;
Ymax - максимальное значение функции;
Ymin - минимальное значение функции.
Знак "-" перед дробью учитывает, что для положительных значений функции
вершина прямоугольника должна лежать выше нулевой линии (значение координаты
Y на экране меньше).
Номер позиции в столбце (ордината) нулевой линии определяется из выражения
(12):
Ymax * DN
KY0 = KYmin + ----------- ( 12 )
Уmах - Ymin
где KYmin - номер позиции в столбце (ордината) верхней границы поля вывода
гистограммы.
В случае, когда Ymin = Ymax (все значения функции одинаковы), все прямоу-
гольники гистограммы будут иметь одинаковую высоту, ординаты их вершин должны
иметь значение KYmin и KYmax. Такой результат достигается, если за минимум
принять 0 при всех положительных значениях функции; при всех отрицательных
значениях функции за максимум принять 0. Прямоугольники гистограммы обычно
заштриховывают. Вывод надписей организуется также, как и при построении гра-
фика с той лишь разницей, что у гистограммы вдоль оси абсцисс будут выводить-
ся не числовые величины, а скорее всего заранее введенные поясняющие надпи-
си.
Пример программы построения гистограммы
Program Gist; { Построение гистограммы }
Uses Crt,Graph;
const n=12; {размерность массива значений функций }
хn=65; {координаты левого }
уn=100; {верхнего угла координ. сетки }
yk=420; {координаты правого}
xk=630; {нижнего угла координ. сетки }
dx=0.3; {отношение ширины прямоугол.гистограммы к промежутку между
прямоугольнмками }
n2=20; {размерность массива координат вершин прямоугольников гистог-
раммы }.
nd=10; {кол-во интервалов на кот. разбивается поле вдоль оси Y для
нанесения надписей }
ns=5; {кол-во позиций в дробной части числа при выводе его на экран }
ms = 2;
type m=array[1..n2] of integer;
m1=array[1..n] of real;
m2=array[1..n] of string[5];
var
f:m1; {массив значений функций}
name:m2; {массив значений надписей под столбцами гистограммы }
х,у :m; {массивы координат вершин прямоугольников }
driver,err, k, {введенное кол-во значений функций }
i, {параметр цикла}
dy, {расстояние по оси ординат между двумя соседними надписями }
nad, {ордината первой надписи при выводе значений функции }
у0:integer; {ордината нулевой линии }
lх, {ширина прямоугольника гист.}
lу, {масштаб вдоль оси ординат }
fmax,fmin, {макс.и мин. значение функции}
df:real; {разность значений функции, соответствующая интервалу между сосед-
ними значениями при нанесении надписей }
st, {строковая переменная для занесения значения функции при выводе надписи
на экран }
zagolovok {строковая переменная для вывода заголовка гистограммы}:string;
begin {ввод исходных данных }
Textbaekground(Red);
Clrscr;
Textcolor(Blue);
GotoXY(10,5);
Write( ' Заголовок гистограммы > ');
Readln(Zagolovok);
Clrscr;
GotoXY(10,5);
write (' Введите количество значений функции > ');
readln(k);
Clrscr;
GotoXY(10,5);
writeln (' Введите значения функции');
for i:=l to k do
Begin
Write(i:2,' значение функции > ');
readln(f[i]);
end;
Clrscr;
GotoXY(10,5);
Writeln( ' Введите названия под столбцами ');
For i:=1 to k do
Begin
GotoXY(15,7+i);
Write (i:2,' Столбец : ');
ReadIn(Name[i]);
end;
{нахождение минимума и максимума функции}
fmax:=f[1]; fmin:=f[1];
for i:=2 to k do
begin
if f[i] > fmax then fmax:=f[i];
if f[i] < fmin then fmin:=f[i];
end;
lx:=(xk-xn)/(k+(k-1)*dx); {ширина прямоугольника гистограммы}
if fmin>=0 then fmin:=0;
if fmax<0 then fmax:=0;
ly:=(yk-yn)/(fmax-fmin); {масштаб по вертикали}
df:=(fmax-fmin)/nd;
dy:=(yk-yn) div nd;
nad:=yn-4;
y0:=round(fmax*ly+yn); {ордината нулевой линии}
driver:=detect; {инициализация графического режима}
InitGraph(driver,err,'c:\t_pascal\bgi');
Setbkcolor(LightBlue);
Setoolor(LightGray);
Rectangle(xn,yn,xk,yk); {очерчивание поля вывода}
Line(xn,y0,xk,y0); {рисование нулевой линии}
{вывод надписей вдоль оси ординат}
for i:=1 to nd+1 do
begin
Str((fmax-(i-1)*df):ns:ms,st);
OutTextXY(xn-(ns*8+15),nad+(i-1)*dy,st);
Line (xn, yn+(i-1)*dy, xn-3, yn+(i-1)*dy );
end;
SetFillStyle(1,10);
SetColor(1O);
{вычисление координат вершин прямоугольников и рисование прямоу-
гольников}
for i:= 1 to k do
begin
x[i]:=xn+round(ix*(1+dx)*(i-1));
y[i]:=y0;
x[i+k]:=round(x[i]+lx);
y[i+k]:=-round(f[i]>ly)+y0;
Bar(x[i],y[i],x[i+k],y[i+k]);
Rectangle(x[i],y[i],x[i+k],y[i+k]);
end;
For i:1 to k do
Outtextxy(x[i] ,y0+5,name[i]);
Setcolor(lightred);
Settextstyle(0,Horizdir,2);
Outtextxy(400,450,' Нажмите Enter');
Setcolor(LightMagenta);
Settextstyle(0,Horizdir,3);
OuttextXY(100,30,zagolovok);
readln;
CloseGraph;
end.
Построение круговой диаграммы
В круговой диаграмме в отличие от гистограммы изображаемые величины отобра-
жаются не в виде столбиков, а в виде круговых секторов. В качестве исходных
данных при построении диаграммы задается массив значений рассматриваемой ве-
личины (функции). Поле вывода диаграммы удобно задать координатами центра ди-
аграммы и величиной ее радиуса.
При построении круговой диаграммы надо иметь в виду, что графические систе-
мы обычно позволяют вычертить дугу или сектор круга с начальным и конечным
углами, задаваемыми целыми значениями градусов. Поэтому вычертить сектор с
центральным углом меньше 1 нельзя, а дробные значения градусов надо округлять
до целого, что вносит некоторую погрешность.
Круговые диаграммы наиболее удобны для представления информации о процент-
ном соотношении. В этом случае сумма всех значений принимается за 100%, чему
соответствует сектор с углом в 360 градусов (т.е. полная дуга). Для вычисле-
ния величины центрального угла сектора, соответствующего очередному значению
функции, следует использовать следующее выражение:
f(i)
Li = ------------------ * 360 ( 13 )
i-1
-------
> f(j)
-------
j=1
где Li - величина центрального угла i-го сектора, i=1,N;
f(i) - i-oe значение функции;
n - общее количество значений функции.
Начальный угол сектора представляет собой сумму центральных углов всех
предшествующих ему секторов, т.е. может быть определен из выражения (14)
i-1
-------
LHi = > Lj ( 14 )
-------
j=1
где LHi - начальный угол i-го сектора.
Конечный угол сектора представляет собой сумму центральных углов всех пред-
шествующих ему секторов, а также текущего сектора, поэтому он определяется
следующим образом:
i
--------
Lki = > Lj ( 15 )
--------
j=1
где Lki - конечный угол i-го сектора.
Таким образом, есть все исходные данные, чтобы построить диаграмму, исполь-
зуя процедуру рисования кругового сектора.
Следует отметить, что процедура одновременно с рисованием сектора осущест-
вляет и его штриховку, что как ,раз и требуется при вычерчивании диаграммы.
Если библиотека графических процедур не содержит процедуру рисования дуги, то
необходимо будет запрограммировать рисование радиусов, разделяющих отдельные
сектора. Координаты одного конца радиуса известны - это (х,у) координаты
центра диаграммы. Координаты другого конца радиуса определяются из следующих
выражений:
Xi = XN + R * cos (LHi)
Yi = YN - R * sin (LHi) ( 16 )
где Xi, Yi - координаты точки пересечения радиуса с дугой окружности i-го
сектора;
R - радиус дуги (диаграммы).
Рядом с каждым сектором диаграммы необходимо вывести соответствующее число-
вое значение функции или любую другую поясняющую надпись. Надпись будем выво-
дить рядом с центром дуги каждого сектора.
Угол, соответствующий центру дуги сектора, может быть найден из выражения
(17):
Lki - LHi LHi + Lki
Bi = LHi + -------- = -------- ( 17 )
2 2
Если надпись располагается в правой полуплоскости, то она выводится правее
центра дуги; если в левой полуплоскости - то левее центра дуги. Поэтому можно
записать следующее выражение:
хl = хс + l, 0° <= В <= 90° и 270° <= В <= 360° ( 18 )
xl = хc - ns * 8 - l, 90°<= В <= 270°
где хl - абсцисса точки (номер точки в строке) первой позиции выводимой за-
писи;
хc - абсцисса центра дуги;
l - интервал между записью и дугой диаграммы;
ns - количество позиций, отводимых под запись.
Если надпись рассполагается в верхней полуплоскости, то она должна выво-
диться выше центра дуги, если в нижней полуплоскости - то ниже центра дуги.
Поэтому справедливо соотношение:
Yl = YC - m - 8, если 0°<= В <= 180° ( 19 )
Yl = YC + m , если 180 <= В <= 360°
где Yl - ордината точки (номер точки в столбце) первой позиции выводимой
записи;
YC - ордината центра дуги;
m - интервал между записью и дугой диаграммы.
В рассмотренном алгоритме построения диаграммы предусматривалось, что LHi =
0, т.е. начальный угол первого сектора равен нулю и диаграмма строится в
направлении против часовой стрелки, начиная от горизонтали.
Можно задать некоторый начальный угол LH( 0°<= LH <= 360°), начиная от ко-
торого будут изображаться сектора диаграммы. Поэтому, если LH >< О, то в (14)
и (15) в правую часть в качестве второго слагаемого надо внести LH, в резуль-
тате о чего углы могут иметь значения, превышающие 360.
В программе, поэтому необходимо выполнить анализ значений углов и приведе-
ние их (в случае необходимости) к диапазону 0 - 360. При этом для одного из
секторов может получиться, что начальный угол будет больше конечного. В этом
случае сектор строится из двух секторов: первый со значением углов, равных
полученному начальному и 360, второй со значениями углов 0 и полученному ко-
нечному значению. При использовании процедуры рисования кругового сектора не-
обходимо затем стереть радиус, разделяющий два сектора. Стирание выполняется
рисованием радиуса цветом фона. В данном случае стираемый радиус - это ради-
ус, имеющий горизонтальное направление и отображающий угол 0 с положительным