Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LAB3bak

.pdf
Скачиваний:
2
Добавлен:
12.02.2015
Размер:
697.43 Кб
Скачать

4. Модуль Graph. Графический режим

Графический режим ПК существенно отличается от текстового как по принципам функционирования, так и по возможностям. Графика применяется практически во всех серьезных программных разработках, так как позволяет увидеть результаты расчетов в виде чертежей, графиков, иллюстраций в движении. Фирмой Borland разработана библиотека графических функций (Модуль Graph.tpu) как приложение к Turbo-пакетам фирмы Borland и графические драйверы - файлы *.bgi (Borland Graphics Interface ), обеспечивающие взаимодействие программ с графическими устройствами.

1. Подключение графической библиотеки производится оператором:

Uses Graph;

2. Переключение из текстового режима в графический (инициализация) осуществля-

ется процедурой:

Procedure InitGraph(Gd, Gm, 'way');

где Gd - имя графического драйвера (параметр-переменная),

Gm - номер графического режима монитора (параметр-переменная),

'way' - путь к файлам с графическими драйверами (*. bgi), например, C:\TP\BGI. Первые два параметра должны иметь целый тип, третий параметр строковый.

В графическом режиме изображение формируется из точек (пикселов) разных цветов. Количество точек на экране и число допустимых цветов можно задавать выбором подключаемого драйвера и номером графического режима. Вариации графических режимов весьма разнообразны, особенно для качественных мониторов. Например, адаптер IBM 8514 / A может обеспечить разрешение 1024 х768 точек и 256 цветов.

Приведем таблицу графических возможностей для мониторов EGA, VGA.

Монитор

драйвер

режим

Число точек

Число

Число видео-

 

"Gd"

"Gm"

на экране

цветов

страниц

EGA

EGA

0

640

x 200

16

4

VGA

EGA

1

640

x 350

16

2

VGA

0

640

x 200

16

4

 

VGA

1

640

x 350

16

2

 

VGA

2

640

x 480

16

1

Обычно драйверы подключаются в режиме автоопределения используемого монитора ПК. Для этого перед инициализацией графического режима задается Gd:= Detect; или Gd:= 0;. В этом случае по умолчанию устанавливается режим с наибольшим числом точек на экране, а значение параметра "Gm" игнорируется. Номер наибольшего режима для текущего драйвера возвращает функция Function GetMaxMode:Integer;.

Разрешающую способность для текущего графического режима можно определить функ-

циями, возвращающими максимальные значения координат экрана:

Х

Function GetMaxX: Integer; - по

 

оси "Х";

 

Function GetMaxY: Integer; - по

Y

оси "Y".

 

Начало координат (X= 0, Y= 0) расположено в левом верхнем углу эк-

рана. Ось Х направлена слева направо, ось Y - сверху вниз (Рис.).

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

Procedure CloseGraph.

Простейшие графические процедуры и функции

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

Procedure SetBkColor(N: Word); - установить цвет "N" для пикселов фона (по умолчанию установлен черный цвет фона).

Procedure SetColor(N: Word); - установить цвет "N" для выводимых линий (По умолчанию установлен белый цвет).

Procedure PutPixel(X, Y: Integer, N: Word); - высветить цветом "N" пиксел с коорди-

натами X, Y.

Function GetMaxColor: Integer; - функция возвращает максимальный номер цвета палитры (цвет задается аналогично цветам текста в модуле Crt).

Procedure Circle(X, Y:Integer, R:Word); - строит текущим цветом окружность с цен-

тром X, Y и радиусом R.

Procedure Line(x1, y1, x2, y2: Integer); - строит текущим цветом отрезок прямой линии от точки с координатами x1, y1 к точке с координатами x2, y2.

Procedure Rectangle(x1, y1, x2, y2: Integer); - строит текущим цветом прямо-

угольник с левым верхним углом в точке с координатами x1, y1 и правым нижним углом в точке с координатами x2, y2.

Function GetPixel(X, Y: Integer): Word; - функция возвращает цвет пиксела с координатами X, Y.

Procedure ClearDevice; - очищает графический экран, закрашивает его цветом фона устанавливает указатель текущей позиции в точку с координатами (0, 0)

Пример 1.

 

 

Uses Crt, Graph;

 

 

var

{ раздел описаний}

ch: char;

 

 

Gd, Gm, Gx, Gy, xc, yc: integer;

 

 

Begin

 

 

Gd:=Detect;

 

 

InitGraph(Gd,Gm,'C:\tp\bgi');

(* инициализация графики *)

Randomize;

 

 

Gx:=GetMaxX; Gy:=GetMaxY;

 

 

{----------------------------------------------------------

 

 

Фрагмент N 1 программы "небо в алмазах"

( рисование пикселов ).

--------------------------------------------------------------SetColor(0);

 

}

 

 

Repeat

 

 

i:= 9 + random(7);

 

 

xc:= random(Gx);

 

 

yc:= random(Gy);

 

 

PutPixel(xc, yc, i);

 

 

Circle(xc, yc, 3)

 

 

Until KeyPressed;

 

 

{----------------------------------------------------

 

}

While KeyPressed do ch:= ReadKey;

 

{ очистка буфера клавиатуры }

CloseGraph;

 

{ закончить работу в графическом режиме }

End.

 

 

После инициализации графики определяются переменные Gx, Gy - максимальные значе-

ния координат по осям X, Y. Назначается черный цвет для линий, которые будут выводиться. Затем в цикле повторяется до нажатия любой клавиши высвечивание точек (пикселов) с номерами цвета "i" от 9 до 15 и координатами xc, yc. Значения координат точек и номеров цвета определяются из заданного диапазона функцией Random. Чтобы точки не "забивали" экран, некоторые из них "гасятся" окружностью радиусом 3 пикселя с центром в появившейся точке.

Пример 2. Построение функции Y=Abs(Sin(x)).

program Funk;

 

uses Graph;

(*подключение графической библибтеки*)

var x, y,h,xk,xn:real;

 

gd,gm:Integer;

 

function f(x:real):real;

(* подпрограмма-функция вычисления abs(sin(x)) *)

begin

 

f:=abs(sin(x))

 

end;

 

Begin

(*начало главной программы*)

gd:=Detect;

 

Initgraph(gd,gm,'c:\bp\bgi');

(*включение графического режима*)

xn:=-10; xk:=10;

(*начало и конец по оси абсцисс х*)

h:= (xk-xn)/1000;

(*величина шага приращения аргумента*)

x:=xn;

 

while x<xk do

 

begin

 

y:=f(x);

(*вычисление функции в точке*)

putpixel(round(x*30+300),round(200-y*200),white); {строим точку на экране}

x:=x+h

(*переход к следующей точке*)

end;

 

readln

 

end.

 

Рис. 2. Метод половинного деления

5. Численное решение алгебраических и трансцендентных уравнений

Метод половинного деления

Блок-схема алгоритма метода половинного деления представлена на рис. 1. Он состоит из следующих операций. Сначала вычисляются значения функций в точках, расположенных через равные интервалы на оси х. Это делается до тех пор, пока не

Рис. 1 Блок-схема алгоритма половинного деле-

ния

будут найдены два последовательных значения функции f(хп) и f(xn+1), имеющие противоположные знаки. (Напомним, если функция непрерывна, изменение знака указывает на существование корня.)

Затем по формуле

вычисляется среднее значение х в интервале значений [xn, хп+1] и находится значение функции f(хср). Если знак f(хср) совпадает со знаком f(хп), то в дальнейшем вместо f(хп) используется f(хср). Если же f(хср) имеет знак, противоположный знаку f(xn), т. е. ее знак совпадает со знаком f(хп+1), то на f(xср) заменяется это значение функции. В результате интервал, в котором заключено значение корня, сужается. Если f(хср) достаточно близко к нулю, процесс заканчивается , в противном случае он продолжается. На рис. 2 эта процедура показана графически. Хотя метод половинного деления не обладает высокой вычислительной эффективностью, с увели-

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

Метод хорд.

В основе этого метода лежит линейная интерполяция по двум значениям функции, имеющим противоположные знаки. При отыскании корня этот метод нередко обеспечивает более быструю сходимость, чем предыдущий. Блок-схема алгоритма метода хорд дана на рис. 3. Счет ведется следующим образом. Сначала определяются значения функции в точках, расположенных на оси х через равные интервалы. Это делается до тех пор, пока не будет найдена пара последовательных значений функции f(хп) и f(хп+1), имеющих противоположные знаки. Прямая, проведенная через эти две точки, пересекает ось х при значении

Рис. 3. Блок-схема алгоритма метода хорд.

Метод Ньютона

Это значение аргумента используется для определения значения функции f(x*), которое сравнивается со

значениями функций f(xn) и f(xn+l) и в дальнейшем используется вместо то-

го из них, с которым оно совпадает по знаку. Если значение f(x*) недостаточно близко к нулю, то вся процедура повторяется до тех пор, пока не будет достигнута необходимая степень сходимости. На рис. 4 процесс решения показан графически.

Рис. 4 Метод хорд.

Метод последовательных приближений, разработанный Ньютоном, очень широко используется при построении итерационных алгоритмов. Его популярность обусловлена тем, что в отличие от двух предыдущих методов для определения интервала, в котором заключен корень, не требуется находить значения функции с противоположными знаками. Вместо интерполяции по двум значениям функции в методе Ньютона осуществляется экстраполяция с помощью касательной к кривой в данной точке. На рис. 5 показана блок-схема алгоритма этого метода, в основе которого лежит разложение функции f(x) в ряд Тейлора

f (xn + h) = f (xn ) + hf '(xn ) + h2 f (xn )+....

2

Члены, содержащие h во второй и более высоких степенях, отбрасываются; используется соотношение xn+h=xn+1. Предполагается, что переход от хn к xn+1 приближает значение функции к нулю так, что f(xn+h)=0. Тогда

xn+1=xn-f(xn)/f’(xn)

Значение xn+1 соответствует точке, в которой касательная к кривой в точке хп пересекает ось х. Так как кривая f(x) отлична от прямой, то значение функции f(xn+1)

Рис. 5 Блок-схема алгоритма Ньютона.

скорее всего не будет в точности равно нулю. Поэтому вся процедура повторяется, причем вместо хп используется хп+1. Счет прекращается по достижении достаточно малого значения f(xn+l). На рис. 6 процесс решения уравнения методом Ньютона показан графически. Совершенно ясно, что быстрота сходимости в большой мере зависит от удачного выбора исходной точки. Если в процессе итераций тангенс угла наклона

Рис. 6 Метод Ньютона

касательной f' (х) обращается в нуль, то применение метода осложняется. Можно также показать, что в случае бесконечно большого f"(x) метод также не будет достаточно эффективным. Так как условие кратности корней имеет вид f(x) = f' (х)= 0, то в

этом случае метод Ньютона не обеспечивает сходимость. Отметим, что иногда используется другой способ контроля сходимости, состоящий в сравнении хп и xn+l.

Метод секущих

Один из недостатков метода Ньютона состоит в том, что, пользуясь им, приходится дифференцировать функцию f(x). Если нахождение производной затруднено, то можно воспользоваться некоторым приближением, которое и составляет основу метода секущих. Заменив производную f'(x), используемую в методе Ньютона

xn+1 = xn f (xn ) , f '(xn )

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

F‘(xn)= f (xn ) f (xn1 ) , xn xn1

получим следующую итерационную формулу:

xn+1 = xn f (xn ) f '(xn )

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

Метод простой итерации

Для применения этого метода уравнение f(x) =0 обязательно приводится к следующему виду:

x = g(x).

Практически к такому виду можно привести любое уравнение. Тогда, соответствующая итерационная формула имеет вид

xп+1 = g(xn).

Блок-схема алгоритма метода представлена на рис. 7. Простота метода простой итерации делает его привлекательным, однако не следует забывать, что и этому методу присущи недостатки, так как он не всегда обеспечивает сходимость. Поэтому для любой программы, в которой используется этот алгоритм, необходимо предусматривать контроль сходимости и прекращать счет, если сходимость не обеспечивается.

Рис. 7 Блок-схема метода простой итерации.

Пример решения уравнения

Предстоит решить уравнение x-tgx=0

воспользовавшись рассмотренными выше методами.

1. Перед решением необходимо:

Определить интервалы, в которых находятся корни уравнения. Это необхо-

димо сделать, чтобы выбрать начальное значение х. Здесь можно, например, изобразить график зависимости tgx и х, из которого следует, что значение первого ненулевого корня уравнения заключено между 3 и 2. Поэтому примем значение х=4.5.

2. Уточнить значение корня, решением уравнения используя рассмотренные методы (Внимание! Используемые методы сами не находят корни уравнения, а лишь уточняют их значение.). Поэтому, очень важен пункт 1, в котором определяют интервалы нахождения корня. Если интервал определен неверно (т.е. там корня нет корня), то программа обычно зацикливается:

а) Метод половинного деления

program urdel2;

(*Программа решения трансцендентного уравнения*)

(*

 

F(X)=X-TAN(X)=0

*)

(*

методом половинного деления

*)

(* Счет прекращается при F=e менее 0.00001

*)

var

 

 

 

 

i:integer;

 

 

 

xh,xk,xcp,xn,xn1,fxn,fxcp,x,e:real;

 

function F(x:real):real;

 

 

begin

 

 

 

 

f:=x-sin(X)/COS(x)

 

 

end;

 

 

 

begin

 

 

 

e:=0.0001; {задание точности}

 

xh:=2;

{начальное и }

 

xk:=5.5;

{конечное значение интервала }

 

writeln('------------------');

 

 

writeln('iteration number');

 

writeln('------------------');

 

 

xn:=xh;

 

 

 

xn1:=xk;

 

 

 

i:=0;

{кол-во иттераций вычисления интервалов}

 

repeat

 

 

 

 

xcp:=(xn+xn1)/2;

(*определение середины*)

 

fxn:=f(xn);

(*определение функции в начале*)

 

fxcp:=f(xcp);

(*и в середине промежутка*)

 

if (fxn*fxcp)>0 then xn:=xcp (*знаки в середине и начале*)

 

else xn1:=xcp;

(*совпадают*)

 

 

i:=i+1;

 

 

 

writeln(i:2,' ',xn:6:5);

(*вывод очередной иттерации*)

 

until abs(fxn)<=e;

(*прверка заданной точности*)

write('=================');

end.

б) Метод хорд.

program urdel2;

(*Программа решения трансцендентного уравнения*)

(*

F(X)=X-TAN(X)=0

*)

(*

методом Хорд

*)

(* Счет прекращается при F=e менее 0.00001

*)

var

 

 

 

i:integer;

 

 

 

xh,xk,xcp,xn,xn1,fxn,fxcp,x,e:real;

 

function F(x:real):real;

 

 

begin

 

 

 

f:=x-sin(X)/COS(x)

 

 

end;

 

 

begin

 

 

e:=0.0001;

 

 

xh:=2;

 

 

xk:=5.5;

 

 

writeln('------------------

');

 

writeln('iteration

number');

 

writeln('------------------

');

 

xn:=xh; xn1:=xk;

 

 

i:=0; repeat

xcp:=xn-f(xn)*((xn1-xn)/(f(xn1)-f(xn))); fxn:=f(xn);

fxcp:=f(xcp);

if (fxn*fxcp)>0 then xn1:=xcp

else xn:=xcp;

 

i:=i+1;x:=f(xn);

 

writeln(i:2,' ',xn:6:5,x);

 

until abs(f(xn))<=e;

{проверка заданной точности, при которой заканчива-

ется вычисление} write('=================');

end.

в) Метод Ньютона

program urnewton;

(*Программа решения трансцендентного уравнения*) (* F(X)=X-TAN(X)=0 *)

(*Методом Ньютона. Счет прекращается при F=e менее 0.00001*)

var

i:integer;

f,df,x,e:real;

 

 

 

begin

 

 

 

e:=0.0001;

(*указанная точность*)

x:=4.5;

(*начальное значение*)

writeln('------------------');

 

 

writeln('iteration number');

(* шапка таблицы*)

writeln('------------------');

 

 

i:=0;

(*обнуление счетчика циклов*)

repeat

 

 

 

f:=x-sin(X)/COS(x);

 

(* вычисление функции *)

df:=1.0-1./(cos(x)*cos(x));

(*

производной*)

x:=x-F/df; i:=i+1;

(*

 

аргумента*)

writeln(i:2,' ',x:6:5)

(*вывод значений в таблицу*)

until abs(f)<=e;

(*проверка точности*)

write('=================');

end.

Таким образом, метод Ньютона обеспечивает очень быструю сходимость при начальном значении х=4.5 (это можно определить по количеству выполненных иттераций). Отметим, что при начальных значениях х=4.0 или 5.0 сходимость уже не достигается.

г) Метод простой итерации (самый простой и часто используемый способ). Применить указанный метод к нахождению корней уравнения х2=sin(x).

program iter;

(*решение уравнения x2=sin(x)*) (*методом простых итераций*)

var

i:integer;

y,xm,f,df,x,e:real; begin e:=0.0000000001; y:=5.45; writeln('------------------');

writeln('iteration number'); writeln('------------------');

i:=0;x:=0;

while abs(x-y)>e do begin

x:=y;

y:=sqrt(abs(sin(x)));

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]