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

Задача 8.

«Обои для ума».

Приведем отрывок из статьи А. К. Дыодни «Программы, генерирующие узоры для боев», помещенной в американском журнале «В мире науки», 1986, № 11.

«Обычные обои печатаются вращающимся цилиндром, на котором выгравиро­ван узор. При каждом обороте цилиндра отпечатывается одно и то же изображе­ние. А вот компьютер может воспроизводить затейливые узоры, которые я назы­ваю «обоями для ума» и которые, вообще говоря, не повторяются или, во всяком случае, повторяются не полностью. Изображение все время проявляется в новых конфигурациях, слева и справа, внизу и вверху. Интересно понаблюдать за тем, что изменяется и что сохраняется от одной картинки к другой».

Рассмотрим программы, составленные по двум простым алгоритмам из указан­ной статьи, генерирующие множество интересных, разнообразных и непредсказу­емых узоров. Их авторы — Дж. Коннет и Б. Мартин. Обе программы родились под влиянием множеств Мандельброта», — пишет А. К. Дьюдни.

Решение.

1. ПрограммаДж.Коннета.

А. К. Дьюдни: «Коннет не удовлетворился изображением множеств Мандельб­рота и занялся исследованием других формул. В конце концов он остановился на формуле х2+у2 и отказался от итераций. Его программа систематически сканиру­ет решетчатую область на плоскости. Для каждой точки (х,у) она вычисляет значе­ние формулы и выделяет целую часть из полученного результата. Если это целое число оказывается четным, точка (х,у) окрашивается в черный цвет, если нечет­ным, то в белый. Большинство рисунков не утрачивают свою красоту при выборе любых цветов».

Program Examp_33;

Uses crt, graph;

Const k=0.01;

Var x,y,z:LongInt;

Procedure Graphinterface;

Var

driver, mode, error:Integer;

s:String;

NL:Byte Absolute $0000:$0417;

Begin

driver:=detect;

s:='';

Initgraph(driver,mode,s);

error:=GraphResult;

if error<>GrOk then

begin

writeln(GraphErrorMsg(Error));

Halt(error)

end

end;

begin

Graphinterface;

for x:=1 to GetMaxX do

for y:=1 to GetMaxY do

begin

if KeyPressed then Exit;

z:=sqr(x)+sqr(y);

if Odd(Trunc(z*k)) then PutPixel(x,y,15)

else PutPixel(x,y,7);

end;

Readln;CloseGraph;

End.

Функцию z22 можно заменить на другую, например: z22, z=х*у, z=ехр(x*y/20000), z=arctg(х/у) и т.д. Вместо семейства окружностей на экране будут изображаться семейства гипербол или других кривых. При изме­нении коэффициента k уменьшается или увеличивается рассматриваемая область вокруг начала координат. Можно исследовать узоры и на периодичность, которая в некоторых случаях выражена очень ярко. «Обои Коннета выглядят значи­тельно интереснее при уменьшении увеличения, когда вы как бы отходите от сте­ны. Концентрические круги будто растворяются в замысловатом узоре первичных и вторичных окружностей, напоминающих муаровые кружева. По мере снижения степени увеличения, как по мановению волшебной палочки, появляются все но­вые и новые отличающиеся от предыдущих узоры», - пишет А. К. Дьюдни.

2. Программа Б. Мартина.

А. К. Дьюдни: «Мартин принял на вооружение идею Мандельброта итериро­вать формулу от начального числового значения - зародыша, но на этом сходство их методов заканчивается. Обои Мартина основаны на итерациях, применяемых к обычным действительным числам. Он предлагает, например, следующие две фор­мулы, которые могут породить потрясающие, отличающиеся довольно сложным узором изображения: х=у-sign(х)*[abs(Ь*х-с)]1/2 и у=а-х. Функция sign(х) принимает значение 1 или -1 в зависимости от того, положителен или отрицателен аргумент х.

Program Examp_34;

Uses crt, graph;

Const n=5000000;

x0=320;y0=240;k1=1.4;

k2=1;a=1.3;b=-1.3;c=-13;

Var sign:Integer;

x,y,old:Real;i:1..n;

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;

x:=0;y:=0;

for i:=1 to n do

begin

if KeyPressed then Exit;

PutPixel(Round(x0+k1*x),

Round(y0+k2*y),(i mod 6)+9);

if x<0 then sign:=-1 else sign:=1;

old:=y;

y:=a-x;

x:=old-sign*sqrt(abs(b*x-c));

end;

end.

В программе константа п задает количество итераций, параметры а, b и с опре­деляют узор, коэффициенты k1 и k2 позволяют увеличивать или уменьшать рису­нок, а также изменять угол, под которым виден узор.