Иногда у программиста бывают моменты, когда хочется написать что-то “just for fun”. В данном посте таким примером послужит простое консольное приложение, которое строит множество Мандельброта из определенных символов.

Немного теории. Каждая позиция в изображение множества Мандельброта соответствует комплексному числу вида N = х + y*i, где х представляет вещественную часть, у— мнимую, а i — квадратный корень из -1. Координаты х и у позиции на изображении соответствуют частям х и у в комплексном числе. Для каждой позиции в изображении выполняется проверка аргумента N, получаемого вычислением квадратного корня из х*х + у*у. Если его значение больше или равно 2, тогда считается, что позиция, соответствующая данному числу, имеет значение 0. Если же значение аргумента оказывается меньше 2, тогда оно заменяется значением N*N — N (дающим в результате N = (х*х — у*у — х) + B*х*у — у) *i) и снова подвергается проверке. Если это значение оказывается больше или равно 2, тогда считается, что позиция, соответствующая этому числу, имеет значение 1. И этот процесс продолжается до тех пор, пока либо не будет присвоено значение позиции в изображении, либо не будет выполнено определенное количество итераций. На основании тех значений, что присваиваются каждой точке в изображении, в графической среде на экране отображался бы пиксель определенного цвета. Однако
поскольку в данном примере используется текстовый режим, вместо пикселей на экран выводятся символы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| // Построение множества Мандельброта "just for fun".
using System;
class Program
{
static void Main(string[] args)
{
double realCoord, imagCoord; // Мнимая и вещественные части числа N
// Переменные для временного хранения информации во время вычислений
double realTemp, imagTemp, realTemp2, arg;
int iterations; // Кол-во итераций
// Циклы for для циклической обработки охватывающих все изображение координат
for (imagCoord = 1.2; imagCoord >= -1.2; imagCoord -= 0.05)
{
for (realCoord = -0.6; realCoord <= 1.77; realCoord += 0.03)
{
// Инициализируем некоторые переменные
iterations = 0;
realTemp = realCoord;
imagTemp = imagCoord;
arg = (realCoord * realCoord) + (imagCoord * imagCoord);
// Цикл while для выполнения итерации
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;
}
/* После сохранения значения для текущей точки в iterations применяется
* оператор switch для выбора символа, выводимого на экран. Здесь используются только 4
* разных символа вместо 40 возможных, а также операция % для того, чтобы значения 0,
* 4, 8 и т.д. давали один символ, значения 1, 5, 9 и т.д. — другой и далее в том же духе */
switch (iterations % 4)
{
case 0:
Console.Write (".") ;
break;
case 1:
Console.Write("o");
break;
case 2:
Console.Write("O");
break;
case 3:
Console.Write("@");
break;
}
}
Console.Write("\n");
}
Console.ReadKey();
}
} |