1й пост будет о фракталах.
Небольшая справка: Фрактал — сложная геометрическая фигура, обладающая свойством самоподобия, то есть составленная из нескольких частей, каждая из которых подобна всей фигуре целиком.
Рассмотрим один из самых простых примеров - множество Мандельброта.
Оно описывается итеративной последовательностью на комплексной плоскости.
где С для множества Мандельброта это
x,y координаты текущей точки.
Алгоритм построения до смешного прост, благодаря найденному ещё в начале 20 века условию, как только модуль
окажется больше 2, последовательность станет стремиться к бесконечности, т.е. когда сумма квадратов действительной и мнимой частей станут больше 4.
Приведу пример метода на C# который реализует метод построения данного фрактала, вывод происходит в объект img класса Bitmap.
Radius задаёт как раз тот предел выше которого множество уходит в бесконечность;Небольшая справка: Фрактал — сложная геометрическая фигура, обладающая свойством самоподобия, то есть составленная из нескольких частей, каждая из которых подобна всей фигуре целиком.
Рассмотрим один из самых простых примеров - множество Мандельброта.
Оно описывается итеративной последовательностью на комплексной плоскости.
где С для множества Мандельброта это
x,y координаты текущей точки.
Алгоритм построения до смешного прост, благодаря найденному ещё в начале 20 века условию, как только модуль
окажется больше 2, последовательность станет стремиться к бесконечности, т.е. когда сумма квадратов действительной и мнимой частей станут больше 4.Приведу пример метода на C# который реализует метод построения данного фрактала, вывод происходит в объект img класса Bitmap.
public void GenerateMandelbrot(int Radius,int MaxIter,double step)
{
//Помещаем начало координат в середину изображения
int Mx = img.Width / 2;
int My = img.Height / 2;
//Производим проход по каждой точке и определяем принадлежит ли она множеству
for (int y = -My; y < My; y++)
{
for (int x = -Mx; x < Mx; x++)
{
double r=x*step,im=y*step;// при изменении положения изменяем начальные значения действительной и мнимой частей
int iterations = 0;//обнуляем итерации при перемещении
while (r * r + im * im < Radius * Radius && iterations<MaxIter)
{
double tmpR = r * r - im * im + x*step;
double tmpIm = 2 * r * im + y*step;
r = tmpR;
im = tmpIm;
iterations++;
}
if (iterations < MaxIter)//В случае если множество ушло в бесконечность делаем пиксель белым
img.SetPixel(Mx + x, My + y, Color.FromArgb(255, 255, 255));
else img.SetPixel(Mx + x, My + y, Color.Black);//Если же он приналежит множеству - чёрным
}
}
}
MaxIter - максимальное количество итераций после которого мы прерываем наш цикл. Это нужно для нахождения точек принадлежащих множеству, а это точки которые никогда не достигнут предела и не уйдут в бесконечность.
step - позволяет нам выбирать "увеличение" нашего фрактала. т.к. если мы будем работать с реальными масштабами, то уже на 2м пикселе от начала координат наше множество закончиться.
В цикле мы считаем Z пока множество не уйдёт в бесконечность или не пройдёт достаточное количество итераций.
В результате для Radius=2,MaxIter=1000,step=0.003 мы получим такую картину
Естественно чем больше количество итераций, тем более точно наше множеству будет соответствовать правильному множеству.
Теперь же я предлагаю расширить наш метод.
И вместо
подставить С=a+b*i, которое будет сохранятся константным на всей продолжительности. Также несколько изменим метод окраски. Теперь мы будет красить в 16 оттенков серого. Для этого немного изменим код
public void GenerateMandelbrot(double a,double b,int Radius,int MaxIter,double step)
{
int Mx = img.Width / 2;
int My = img.Height / 2;
for (int y = -My; y < My; y++)
{
for (int x = -Mx; x < Mx; x++)
{
double r=x*step,im=y*step;
int iterations = 0;
while (r * r + im * im < Radius * Radius && iterations<MaxIter)
{
double tmpR = r * r - im * im + a;
double tmpIm = 2 * r * im + b;
r = tmpR;
im = tmpIm;
iterations++;
}
if (iterations < MaxIter)
//Раскраска 16 оттенками серого
img.SetPixel(Mx + x, My + y, Color.FromArgb(255 -
(iterations % 16) * 16, 255 - (iterations % 16) * 16, 255 - (iterations % 16) * 16));
else img.SetPixel(Mx + x, My + y, Color.Black);
}
}
}
Если же ещё немного поиграть со значениями(a=0,b=1,Radius=2,MaxIter=1000,step=0.003) то можно получить, например, такое
Можно ещё долго эспериментировать со значениями и получать множество красивых фракталов. В следующей статье я попробую рассказать о разных методах раскраски фракталов, для получения действительно красивых изображений.




Комментариев нет:
Отправить комментарий