паскаль. Методическое пособие для учителя Томск2006 Графика Принципы работы с видеотерминалом в системе Turbo Pascal 0
![]()
|
Программа фрактального морфинга
Помня афоризм о том, что чем шире угол зрения, тем он тупее, ограничимся рассмотрением только лишь комплексных чисел. К сожалению, их (комплексные числа) периодически исключают из школьной программы, а это один из красивейших разделов математики. Комплексное число состоит из реальной (обычного числа) и мнимой части. Мнимая часть содержит квадратный корень из -1, i=(-1)1/2. Разработаны правила действий с комплексными числами, основанные на том, что i в квадрате равно минус 1 (i2= -1). Комплексные числа имеют прикладное значение во многих областях науки, являются основным аппаратом для расчетов в электротехнике и связи. Если на плоскости по горизонтальной оси откладывать реальные числа, а по вертикальной – мнимые, то каждому комплексному числу будет соответствовать точка на этой плоскости. Именно эта возможность «видеть» комплексные числа и действия над ними поразила меня еще в школе, когда о фракталах и речи не было. Например, известно, что корни третьей степени из единицы (один реальный и два комплексных) расположены в вершинах равностороннего треугольника, а корни кубические из –1 тоже лежат на вершинах равностороннего треугольника, но отраженного относительно первоначального вокруг вертикальной оси. А корни седьмой степени из любого числа лежат на вершинах правильного семиугольника. Каждому комплексному числу соответствует точка на плоскости. Возведем число в квадрат – появляется другая точка, еще раз возведем в квадрат (или любую другую степень), появляется новая точка на плоскости. Потом эту простейшую операцию повторим многократно с получающимся каждый раз новым комплексным числом. В зависимости от начального числа могут быть три варианта: процесс пошел вразнос, число резко растет, уходит «из поля зрения», это не интересно; число быстро уменьшается и исчезает, еще менее интересно; да, да, теперь самое потрясающее. При некоторых начальных значениях новые числа группируются внутри некоторой области, а при отображении их на плоскости появляются невероятные изображения. Это группирование возводимых в квадрат комплексных чисел впервые подметил и описал Жюлиа в 1916 году. И это, так называемое множество Жюлиа, послужило отправной точкой для Бенуа Р. Мандельброта, математика из Исследовательского центра им. Томаса Уотстона при IBM, впервые предложившего термин «фрактал» для описания объектов, структура которых повторяется при переходе к все более мелким масштабам. Так как появляющиеся картинки обладают всеми признаками фракталов. Многие авторы оспаривают первенство Мандельброта, ссылаясь на более ранние работы, но название, тем не менее, закрепилось (как-то же множество надо называть). Подробности выяснения приоритета можно найти в журнале «В мире науки» (Scientific American) №6/1990 г. Однако вернемся к множеству. Суть технологии его получения состоит в следующем. Берется комплексное число. Выбранное число возводится в квадрат и прибавляется какое-то фиксированное постоянное число. Это число тоже комплексное, то есть имеет действительную и мнимую части, подбирая их мы можем регулировать процесс, получая самые причудливые картины. Простейшая итерационная формула Zнов=Z2стар + С, соответствующая множеству Жюлиа, нарисует подобие куклы-неваляшки. Края ее размыты, как бы лохматые. В них то и происходит самое таинство. Почему же фракталы так красивы? Так сказочно, обворожительно, волнующе (какие еще есть эпитеты?) красивы. Фракталы связаны кроме всего прочего и с биологией. Нас же более интересует то, что некоторые фрактальные рисунки похожи на клеточные организмы. Итак, мы рассматриваем в цикле (точнее, в двух циклах, по x и по y) точки плоскости в выбранном диапазоне. Каждую точку превращаем в комплексное число, получая действительную составляющую (RE) из координаты по х и мнимую составляющую (IM) из координаты по y с помощью масштабного коэффициента. Для возведения комплексного числа в квадрат применим подпрограмму QWA. Поясним, как получились ее формулы. Запишем комплексное число в виде z=a+bi, где a и b его дейстительная и мнимая составляющие. Найдем квадрат этого числа: z2=(a+bi)*(a+bi)=a2+abi+abi+(bi)2=a2+2abi-b2=(a2-b2)+2abi или в наших символах re1=re*re-im*im – действительная часть после возведения в квадрат im1=2*re*im – мнимая часть после возведения в квадрат. Теперь открываем цикл (со счетчиком v), в теле которого возводим число в квадрат, вызывая QWA, потом добавляем фиксированное число к каждой составляющей комплексного числа, потом проводим анализ для выхода из цикла, например, по достижению переменными re и im какого либо значения. Значение счетчика цикла v запоминается и именно оно служит для определения цвета в данной точке. В этом и состоит изюминка алгоритма получения красивого изображения – разные точки выходят при разных значениях счетчика и группируются по цветам в замысловатые узоры. После выхода из цикла еще вводим условия для рисования цветом v, а остальные области заполняем черным цветом. Теперь, подбирая масштаб, фиксированное число (точнее две его составляющие), условие выхода и условия рисования получим картинку, соответствующую приведенному листингу программы. ![]() PROGRAM FRACTAL; USES CRT,GRAPH,DOS; LABEL 1; VAR RE,IM,RE1,IM1: REAL ; V,X,Y : INTEGER; C: STRING; procedure GrInit; { инициализация режима графики } var GraphDriver : Integer; { для графического адаптера } GraphMode : Integer; { для графического режима } ErrorCode : Integer; { для кода ошибки } begin GraphDriver:= Detect; { режим автоопределения } InitGraph(GraphDriver,GraphMode,''); { инициализация} ErrorCode:=GraphResult; { результат инициализации } if ErrorCode <> grOk then { если не успешно, то ...} begin Writeln('Ошибка графики:',GraphErrorMsg(ErrorCode)); Writeln('Программа остановлена.'); Halt (1) end {if} end; PROCEDURE QWA ; BEGIN RE1:=RE*RE-IM*IM ; IM:=2*RE*IM ; RE:=RE1 ; END ; {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} BEGIN GRINIT; SETFILLSTYLE(1,WHITE) ; BAR(0,0,640,480) ; X:=-320 ; REPEAT Y:=-240 ; REPEAT V:=0 ; RE:=0.012435*X ; IM:=0.012435*Y ; REPEAT QWA ; RE:=RE+0.937106 ; IM:=IM-3.0 ; IF RE*RE > 100 THEN GOTO 1 ; IF IM*IM > 100 THEN GOTO 1; V:=V+1 ; UNTIL V>40 ; 1:IF ( ABS(RE) < 10 ) OR (ABS(IM) < 10) THEN BEGIN PUTPIXEL((X+320),(Y+240),V+10); END ELSE PUTPIXEL((X+320),(Y+240),0) ; Y:=Y+1 ; UNTIL Y > 241 ; X:=X+1 ; UNTIL X>320 ; C:=READKEY ; CLOSEGRAPH; END. Попробуйте поменять параметры и вы увидите, как фиксированное число влияет на вид сердцевины рисунка, условия выхода и условия рисования на заполненность его цветом и на длину колючек, причем ограничения по re и по im влияют каждый на свои колючки, поиграйте с программой – невозможно оторваться от этих экспериментов. А мы делаем следующий шаг – задаемся вопросом, а почему бы не попробовать возводить число в куб? Никаких ограничений нет, и мы создаем подпрограмму KUB. Помня шутку о том, что каждая добавленная в книгу формула вдвое сокращает число ее покупателей, выводить формулу куба комплексного числа не будем, вы это запросто проделаете сами, помня, что i2=-1. А вот и текст подпрограммы: PROCEDURE KUB ; BEGIN RE1:=RE*(RE*RE-3*IM*IM) ; IM1:=IM*(3*RE*RE-IM*IM) ; RE:=RE1 ; IM:=IM1 ; END ; И картинка от запуска той же программы с единственной заменой QWA на KUB из которой видно, что внутри нашего фрактала плавают теперь не два, а три организма, внутри которых тоже не по два, по три более мелких. ![]() Дальше вы уже знаете, что можно сделать – задать два раза подряд QWA ; QWA для возведения в четвертую степень и получить организм с четырьмя штучками внутри. ![]() Задав QWA; KUB; получим шестую степень, а KUB; KUB; - соответственно, девятую степень комплексного числа. Варианты сочетаний степеней с подобранными к ним фиксированным числом и условиями выхода бесконечны. Приведу лишь два самых интересных. На первом из них мы видим сказочное окно в волшебный мир, ![]() вот фрагмент программы для его получения. :=-320 ; REPEAT Y:=-240 ; REPEAT V:=0 ; RE:=0.0075*X ; IM:=0.0075*Y ; REPEAT QWA; kub; RE:=RE-0.1 ; IM:=IM+0.828201638 ; IF RE*RE > 10 THEN GOTO 1 ; IF IM*IM > 10 THEN GOTO 1; V:=V+1 ; UNTIL V>13 ; 1: IF ( ABS(RE) > 241 ; X:=X+1 ; UNTIL X>320 ; А на втором, самом, можно сказать, фрактальном, мы видим страшную сказку из бесконечной вложенности самоподобных элементов. Сначала при мелком масштабе мы видим мрачную черную колючку, внутри которой плавают три голубых организма, тоже с черными колючками, одна из которых, самая страшная, больше других. ![]() Увеличиваем масштаб, опускаясь внутрь чудища, и видим, что в каждом из трех голубых организмов расположились по три красных с черными колючками, одна из которых…, в каждом красном живут по три розовых, в них по три желтых, в них по три белых… и все с черными колючками. ![]() И вот фрагмент кода для этих фантастических существ фрактального микромира. X:=-320 ; REPEAT Y:=-240 ; REPEAT V:=0 ; RE:=0.5+0.00121*X ; IM:=-1+0.00121*Y ; REPEAT KUB; RE:=RE+1.00003 ; IM:=IM+1.01828201638 ; IF RE*RE > 50 THEN GOTO 1 ; IF IM*IM >50 THEN GOTO 1; V:=V+1 ; UNTIL V > 40 ; 1: IF ( ABS(RE) > 10 ) OR ( ABS(IM) > 1000) THEN BEGIN PUTPIXEL((X+320),(Y+240),TRUNC(V+8)) ; END ELSE PUTPIXEL((X+320),(Y+240),0); Y:=Y+1 ; UNTIL Y > 241 ; X:=X+1 ; UNTIL > 320 ; Какой следующий ход в нашем движении по созданию картинок из жизни комплексных чисел? Конечно же переход к полноценному 24-битному представлению цвета, которое позволяют получить языки программирования в среде Windows. Например, Visual Basic, в который мы перенесем отлаженный в Турбо Паскале алгоритм. Даже используя только возведение чисел в квадрат за счет подбора масштаба, фиксированного числа, условия выхода и коэффициентов для каждой составляющей цвета можно получать невероятно красивые картины. Именно ими на 99% заполнены бесконечные фрактальные галереи в Сети. Приводим листинг исполнения и один из бесчисленных вариантов подобранных параметров с полученной картинкой. xmax = 500 ymax = 500 v = 45 m = 7 For x = ss To xmax Step ss For y = ss To ymax Step ss re = (x - 250) / 400 im = -(y - 250) / 400 k = 1 For j = 1 To v k = k + 1 re1 = re * re - im * im - 0.053 im = 2 * re * im + 0.85 re = re1 If Abs(re) > 140 Or Abs(im) > 301 Then Exit For Next j red = (25 * k) Mod 255 green = (24 * k) Mod 255 blue = Int(Abs(k * 23)) Mod 255 Col = RGB(red, green, blue) If ss > 1 Then Line (x + 120, y)-Step(ss, ss),Col, BF If ss = 1 Then PSet (x + 120, y), Col Next y Next x End Sub ![]() Видно, что алгоритм точно такой же, что и в Паскале, только возведение в квадрат не вынесено в подпрограмму. Попробуйте поменять коэффициенты, на которые умножается счетчик цикла для получения разных цветов при выводе точки и вы увидите, как сильно поменяется вид рисунка. Каждое комплексное число вида z=a+bi можно представить в виде z=r*cos(fi)+r*sin(fi), где r=(a2+b2)1/2 – так называемый модуль комплексного числа, а fi=atn(a/b) – угол между отрезком, соединяющим начало координат с нашим числом и осью действительных чисел. Использование формулы Муавра позволяет возводить комплексное число по очень изящному соотношению: zn=rn*cos(n*fi)+rn*sin(n*fi) А самое интересное, что используя эту формулу мы можем возводить комплексное число не только в натуральную, но и в дробную и отрицательную степень. Вообще говоря можно возводить даже и в комплексную степень, но это уже совсем выходит за рамки забав с картинками. Вот пример реализации – картинка, полученная возведением числа в девятую степень с применением формулы Муавра и листинг программы. ![]() pi = 3.14159 xmax = 500 ymax = 500 v = 45 m = 9 For x = ss To xmax Step ss For y = ss To ymax Step ss re = (x - 250) / 200 im = -(y - 250) / 200 k = 1 z = 1 For j = 1 To v k = k + 1 r = Sqr(re * re + im * im) If re <> 0 Then fi = Atn(im / re) If re < 0 Then f i= fi + pi fi1 = f i* m If r > 0 Then r = Exp(m * Log(r)) re = r * Cos(fi1) + 0.254164 im = (r * Sin(fi1) - 0.81) If Abs(r) > 1000 Then Exit For Next j red = (132 * k) Mod 255 green = (228 * k) Mod 255 blue = Int(Abs(130 * k)) Mod 255 Col = RGB(red, green, blue) If ss > 1 Then Line (x + 120, y)-Step(ss, ss), Col, BF If ss = 1 Then PSet(x + 120, y), Col Next y Next x Небольшие тонкости, в которых, впрочем, читатели наверняка разберутся сами: при вычислении угла через арктангенс надо обойти деление на нуль и учесть, что область определения арктангенса первая и четвертая четверть, поэтому для отрицательных значений re к полученному углу добавляется пи. На этом же Арбузе расположен Java-аплет, рисующий фракталы по формуле Муавра, причем масштаб, сдвиги фиксированным числом реальные и мнимые, условие выхода и коэффициенты для каждого цвета можно задавать на свой вкус, любуясь полученными чудесами. Забавляясь с аплетом или с самодельными программами вы заметите, что у появляющихся организмов число отростков или голов равно показателю степени для целых значений степени. ![]() ![]() ![]() Для дробных узор рассыпается, появляются разрывы на контуре, зато при отрицательных значениях показателя степени появляются цветы и фантастические бабочки невиданной красоты. На этом и закончим, успеха вам в экспериментах с таинственной красотой фракталов. СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 1. Информатика(Базовый курс) С. В. Симонович, СПб: Питер, 2001г. Основы языка Turbo Pascal(учебный курс), П. И. Рудаков, М. А. Федотов, Москва: Радио и Связь, 2000г. 2. Основы программирования в задачах и примерах, А. В. Милов, Харьков: ФОЛИО, 2002г. 3. Программирование. С. Симонович, Г. Евсеев, Москва: АСТ – ПРЕСС книга 2000г. 4. Практика программирования, Ю. Кетков, А. Кетков, СПб: БХБ/ Петербург, 2002г. 5. Turbo Pascal. С. А. Немнюгин.- СПб: Издательство «Питер», 2001.-496 с.:ил. 6. Turbo Pascal: учитесь программировать, О. А. Меженный, Москва: изд. дом «Вильямс», 2001г 7. Р. М. Кроновер, Фракталы и хаос в динамических системах, “Постмаркет”, М. 2000 8. Пайтген Х.-О. Рихтер Н.Х. Красота фракталов. М. 1993. с. 176. (94-8/639) 9. Федер Е. М. Фракталы. Мир. 1991 260 с. (91-5/3219) |