|
Программирование >> Программирование с использованием ajax
Описание полученных результатов Рассмотрение деталей, касающихся вычисления множества Мандельброта, выходит за рамки данной главы, но разобраться в том, почему необходимы циклы в приведенном коде, все равно нужно. Те, кому не интересны математические детали, могут спокойно пропустить два следующих параграфа, потому что здесь важным является все-таки понимание кода. Каждая позиция в изображение множества Мандельброта соответствует комплексному числу вида 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++) ;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |