Программирование >>  Программирование с использованием ajax 

1 ... 27 28 29 [ 30 ] 31 32 33 ... 396


Описание полученных результатов

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

Каждая позиция в изображение множества Мандельброта соответствует комплексному числу вида N = X + y*i, где х представляет вещественную часть, у - мнимую, а i - квадратный корень из -1. Координаты х и у позиции на изображении соответствуют частям X и у в комплексном числе.

Для каждой позиции в изображении выполняется проверка аргумента N, получаемого вычислением квадратного корня из х*х + у*у. Если его значение больше или равно 2, тогда считается, что позиция, соответствующая данному числу, имеет значение 0. Если же значение аргумента оказывается меньше 2, тогда оно заменяется значением N*N - N (дающим в результате N = (х*х - у*у - х) + (2*х*у - у) *i) и снова подвергается проверке. Если это значение оказывается больше или равно 2, тогда считается, что позиция, соответствующая этому числу, имеет значение 1. И этот процесс продолжается до тех пор, пока либо не будет присвоено значение позиции в изображении, либо не будет выполнено определенное количество итераций.

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

Теперь вернемся к коду и содержащимся в нем циклам. Начинается код с объявления необходимых для вычислений переменных:

double realCoord, imagCoord;

double realTemp, imagTemp, realTemp2, arg;

int iterations;

Здесь переменные realCoord и imagCoord представляют собой вещественную и мнимую часть числа N, а остальные переменные типа double предназначены для сохранения временной информации во время вычислений. Переменная iterations отвечает за фиксирование информации о количестве итераций, которые будут производиться перед тем, как значение аргумента N (arg) станет равно 2 или больше.

Далее создаются два цикла for для циклической обработки охватывающих все изображение координат (с использованием для изменения счетчиков более сложного синтаксиса, а не ++ и -, который тоже является весьма распространенным приемом):

for (imagCoord = 1.2; imagCoord > = -1.2; imagCoord -= 0.05) {

for (realCoord = -0.6; realCoord <= 1.77; realCoord += 0.03) {

Здесь применялись ограничения, необходимые для отображения основной части множества Мандельброта. Однако их, конечно, можно изменять каким угодно образом и получать, например, крупный план определенной части изображения.

Внутри этих двух циклов содержится код, который имеет отношение только к одной точке во множестве Мандельброта и предоставляет для манипуляций значение N. Именно здесь вычисляется количество требуемых итераций, которое дает значение для прорисовывания для текущей точки.



Сначала инициализируются некоторые переменные:

iterations = 0; realTemp = realCoord; imagTemp = imagCoord;

arg = (realCoord * realCoord) + (imagCoord * imagCoord);

Далее применяется цикл while для выполнения итерации. В случае, когда первоначальное значение аргумента N уже больше 2, лучше использовать цикл while, чем do, потому что тогда подходящий ответ выглядит как iterations = О и никакие дальнейшие вычисления не требуются.

Обратите внимание, что здесь речь идет не совсем о полном вычислении аргумента. Здесь просто получается значение х*х + у*уи осуществляется проверка на предмет того, является ли оно меньше 4. Это упрощает процесс вычисления, поскольку известно, что корнем квадратным из 4 будет 2, и вычислять другие корни квадратные самостоятельно не требуется:

while ((arg < 4) && (iterations < 40)) {

realTemp2 = (realTemp * realTemp) - (imagTemp * imagTemp) - realCoord; imagTemp = (2 * realTemp * imagTemp) - imagCoord; realTemp = realTemp2;

arg = (realTemp * realTemp) + (imagTemp * imagTemp) ; iterations += 1;

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

После сохранения значения для текущей точки в iterations применяется оператор switch для выбора символа, выводимого на экран. Здесь используются только 4 разных символа вместо 40 возможных, а также операция % для того, чтобы значения О, 4, 8 и т.д. давали один символ, значения 1, 5, 9 и т.д. - другой и далее в том же духе:

switch (iterations % 4) {

case 0:

Console.WriteC. ) ;

break; case 1:

Console.Write( o );

break; case 2:

Console.Write( 0 );

break; case 3:

Console.Write( @ ); break;

Команда Console .Write () применяется вместо команды Console .WriteLine () потому, что в данной ситуации не нужно, чтобы каждый выводимый символ отображался в новой строке. В конце одного из находящихся в самой глубине циклов for, однако, все же требуется завершить строку, поэтому в нем просто выводится символ конца строки с использованием соответствующей управляющей последовательности, которая уже демонстрировалась ранее:

Console.Write( \п );



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

Прерывание циклов

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

□ break - приводит к немедленному завершению цикла;

а continue - приводит к немедленному завершению текущей итерации цикла (выполнение продолжается со следующей итерации);

□ goto - позволяет переходить из цикла к выполнению кода с указанной меткой (не рекомендуется использовать, если требуется, чтобы код был легким для восприятия и понимания);

а return - приводит к выходу из цикла и содержащей его функции (более подробно будет рассматриваться в главе 6).

Команда break просто завершает цикл, после чего выполняется строка кода, находящаяся сразу после этого цикла, например:

int i = 1; while (i <= 10) {

if (i == 6) break;

Console.WriteLine( {0} , i++);

Этот код будет выводить на консоль числа от 1 до 5, поскольку по достижении переменной i значения 6 команда break вынуждает цикл завершиться.

Команда continue подразумевает прерывание только текущей итерации, а не всего цикла, как показано ниже:

int i;

for (i = 1; i <= 10; i++) {

if ((i % 2) == 0)

continue; Console.WriteLine(i);

В этом примере, всякий раз, когда остатком деления значения переменной i на 2 будет ноль, оператор continue будет останавливать выполнение текущей итерации, в результате чего на экране будет отображаться только числа 1, 3, 5, 7 и 9.

Третьим способом прерывания цикла является использование оператора goto, как уже показывалось ранее:

int i = 1; while (i <= 10) {

if (i == 6)

goto exitPoint; Console.WriteLine( {0} , i++) ;



1 ... 27 28 29 [ 30 ] 31 32 33 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика