Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Графика в Pascal.doc
Скачиваний:
33
Добавлен:
10.06.2015
Размер:
990.21 Кб
Скачать

Задача 2.

Построить кривые по заданному параметрическому представлению:

1) окружность радиуса r, центр которой совпадает с центром экрана;

2) эллипс с большой и малой полуосями, равными соответственно r1 и r2 и расположенными параллельно осям координат;

3) астроиду: x=bcos3t, y=bsin3t, t[0,2];

4) кардиоиду: x=accost(1+cost), y=asint(1+cost), a>0, t[0,2];

5) строфоиду: x=a(t2-1)/(t2+1), y=at(t2-1)/(t2+1), a>0, t(-,).

Решение:

Параметрическое задание образов широко применяется в компьютерной геометрии и графике. Параметрическое представление кривой на плоскости с координатами x, y – это два уравнения (две функции), явно выражающие обе координаты через значение некоторого производящего параметра: x=(t), y=(t). Параметрические линии по форме могут быть разнообразнее, чем линии, описываемые одним явным уравнением. На них не распространяется ограничение по многозначности, поэтому линии могут быть самопересекающимися.

1. Уже для окружности видны преимущества такого задания. Координаты точек окружности с центром (x0, y0) и радиусом r вычисляются по формулам: x=x0+rcost, y=y0-rsint, в которых центральный угол t является генерирующим параметром. Изменяя его от 0 до 2, мы описываем всю окружность последовательными близко расположенными точками, расстояния между которыми одинаковы. В программе константы x0, y0 и r – это координаты центра окружности и ее радиус; параметр t – типизированная константа со стартовым значением 0.

Program Examp_27;

Uses crt, graph;

Const t:Real=0;

x0=320;y0=240;r=222;

Procedure Graphinterface;

Var

driver, mode, error:Integer;

s:String;

Begin

driver:=detect;

s:=' ';

Initgraph(driver,mode,s);

error:=GraphResult;

if error<>GrOk then

begin

writeln(GraphErrorMsg(Error));

Halt(error)

end

end;

Begin

Graphinterface;

Repeat

putpixel(round(x0+r*cos(t)),

round(y0-r*sin(t)),15);

t:=t+0.001;

Until t>2*pi;

Readln; CloseGraph;

End.

Формулы параметрического задания окружности содержат тригонометрические функции, которые замедляют построение. Учитывая симметрию окружности относительно осей координат и прямых, содержащих биссектрисы кооординатных углов, цикл в приведенной программе можно заменить таким:

{В зазделе описания переменных вставить Var x,y:Integer}

Repeat

x:=Round(r*cos(t)); y:=Round(r*sin(t));

PutPixel(x0+x,y0+y,15); PutPixel(x0+x,y0-y,11);

PutPixel(x0-x,y0+y,14); PutPixel(x0-x,y0-y,10);

PutPixel(x0+y,y0+x,13); PutPixel(x0+y,y0-x,9);

PutPixel(x0-y,y0-x,12); PutPixel(x0-y,y0+x,5);

t:=t+0.001;

Until t>pi/4;}

В этом цикле находятся координаты не всех точек окружности, а только точек дуги от 00 до 450. Для каждой пары вычисленных значений промежуточных переменных x и y сразу рисуются 8 пикселей. Можно также воспользоваться параметрическими уравнениями:

t[0, 1], в которых изменение параметра соответствует дуге окружности от 0 до 900. Здесь полная окружность будет построена симметричным отображением каждой полученной точки относительно оси OX, оси OY и начала координат. За один проход цикла, в котором t изменяется от 0 до 1, рисуются сразу 4 пикселя и не используются тригонометрические функции.

Еще один из возможных способов заключается в применении формул сложения:

cos(x+t)=cosxcost-sinxsint,

sin(x+t)=sinxcost+cosxsint.

Если считать в них t фиксированным приращением параметра и заменить значения sint и cost константами, то станет возможным использование ранее вычисленных значений для нахождения cos(x+t) и sin(x+t) без использования функций синус и косинус.

Вообще существуют очень быстрые алгоритмы для рисования прямых, окружностей, многоугольников и т.д. (известны, например, алгоритмы Брезенхема). Они используются при написании компьютерных игр и графических программ, требующих очень высокой скорости исполнения.

2. Эллипс, оси которого параллельны координатным осям, имеет параметрические уравнения, значительно отличающиеся от уравнений окружности:

x=x0+r1cost, y=y0-r2sint.

Вместо одного радиуса в них используются величины двух полуосей эллипса. Поэтому в блоке констант нужно задать два различных радиуса и незначительно изменить оператор в теле цикла:

PutPixel(Round(x0+r1*cos(t)),

Round(y0-r2*sin(t)),15);

3)-5). Для записи уравнений употребим две функции x(t) и y(t). Построение кривых отличается незначительно стартовыми значениями констант. Можно создать также универсальную программу, учитывающую область значений функций и выполняющую масштабирование.

Program Examp_28;

Uses crt, graph;

Const {3} t:Real=0;r=200;

(*{4} t:Real=0;r=100; *)

(*{5} t:Real=-2*pi; r=50; *)

Var u,v:Real;

Procedure Graphinterface;

Var

driver, mode, error:Integer;

s:String;

Begin

driver:=detect;

s:='';

Initgraph(driver,mode,s);

error:=GraphResult;

if error<>GrOk then

begin

writeln(GraphErrorMsg(Error));

Halt(error)

end

end;

Function x(t:Real):Real;

begin

{3} u:=cos(t); x:=u*sqr(u); {астроида}

(*{4} u:=cos(t); x:=u*(1+u); {кардиоида} *)

(*{5} u:=(sqr(t)-1)/(sqr(t)+1); x:=u;

{строфоида} *)

end;

Function y(t:Real):Real;

begin

{3} v:=sin(t); y:=v*sqr(v);

(*{4} v:=sin(t); y:=v*(1+u); *)

(*{5} y:=t*u; *)

end;

Begin

Graphinterface;

SetViewPort(320,240,320,240,ClipOff);

Repeat

putpixel(round(r*x(t)),round(r*y(t)),11);

t:=t+0.001;

Until t>2*pi;

Readln; CloseGraph;

End.