🎨 Графическое программирование на C#

← Вернуться к модулю 6

Урок 6.2: Фракталы

Модуль 6 ⏱️ ~2.5 часа

Что такое фракталы

Фракталы — это геометрические фигуры, которые имеют самоподобие на разных масштабах. Они создаются с помощью рекурсивных алгоритмов.

Множество Мандельброта

private void DrawMandelbrot(Graphics g, int width, int height)
{
    Bitmap bmp = new Bitmap(width, height);
    int maxIterations = 100;
    
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            double real = (x - width / 2.0) / (width / 4.0);
            double imag = (y - height / 2.0) / (height / 4.0);
            
            int iterations = MandelbrotIterations(real, imag, maxIterations);
            Color color = GetColor(iterations, maxIterations);
            bmp.SetPixel(x, y, color);
        }
    }
    
    g.DrawImage(bmp, 0, 0);
}

private int MandelbrotIterations(double real, double imag, int max)
{
    double zReal = 0, zImag = 0;
    for (int i = 0; i < max; i++)
    {
        double zRealNew = zReal * zReal - zImag * zImag + real;
        double zImagNew = 2 * zReal * zImag + imag;
        zReal = zRealNew;
        zImag = zImagNew;
        if (zReal * zReal + zImag * zImag > 4) return i;
    }
    return max;
}

Дерево Пифагора

private void DrawPythagorasTree(Graphics g, float x, float y, 
    float length, float angle, int depth)
{
    if (depth == 0) return;
    
    float x2 = x + length * (float)Math.Cos(angle);
    float y2 = y - length * (float)Math.Sin(angle);
    
    g.DrawLine(Pens.Black, x, y, x2, y2);
    
    float newLength = length * 0.7f;
    DrawPythagorasTree(g, x2, y2, newLength, angle - 0.5f, depth - 1);
    DrawPythagorasTree(g, x2, y2, newLength, angle + 0.5f, depth - 1);
}

// Вызов
DrawPythagorasTree(e.Graphics, 400, 500, 100, Math.PI / 2, 10);

Рекурсивное рисование

// Снежинка Коха
private void DrawKochSnowflake(Graphics g, PointF p1, PointF p2, int depth)
{
    if (depth == 0)
    {
        g.DrawLine(Pens.Blue, p1, p2);
        return;
    }
    
    PointF p3 = new PointF(
        (2 * p1.X + p2.X) / 3,
        (2 * p1.Y + p2.Y) / 3);
    PointF p4 = new PointF(
        (p1.X + 2 * p2.X) / 3,
        (p1.Y + 2 * p2.Y) / 3);
    
    float dx = p4.X - p3.X;
    float dy = p4.Y - p3.Y;
    float angle = (float)Math.Atan2(dy, dx) - (float)Math.PI / 3;
    float length = (float)Math.Sqrt(dx * dx + dy * dy);
    PointF p5 = new PointF(
        p3.X + length * (float)Math.Cos(angle),
        p3.Y + length * (float)Math.Sin(angle));
    
    DrawKochSnowflake(g, p1, p3, depth - 1);
    DrawKochSnowflake(g, p3, p5, depth - 1);
    DrawKochSnowflake(g, p5, p4, depth - 1);
    DrawKochSnowflake(g, p4, p2, depth - 1);
}

Практическое задание

Задание: Фракталы

  1. Создайте приложение для отображения множества Мандельброта
  2. Добавьте возможность масштабирования и перемещения
  3. Реализуйте выбор цветовой схемы

Проверка знаний

Ответьте на вопросы, чтобы проверить, насколько хорошо вы усвоили материал:

1. Что такое фрактал?
  • Геометрическая фигура с самоподобием
  • Тип изображения
  • Алгоритм сжатия
  • Формат файла
2. Что такое множество Мандельброта?
  • Фрактальное множество, определяемое итерациями комплексных чисел
  • Геометрическая фигура
  • Алгоритм сжатия
  • Тип данных
3. Что такое рекурсивное рисование?
  • Рисование, при котором функция вызывает сама себя
  • Рисование в цикле
  • Рисование с задержкой
  • Рисование по шаблону