Фрактальные кривые

XXIX Международный конкурс научно-исследовательских и творческих работ учащихся
Старт в науке

Фрактальные кривые

Деменев С.А. 1
1МАОУ "Гимназия №17"
Проничева С.А. 1
1МАОУ "Гимназия №17"
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

Введение

Традиционный школьный курс геометрии опирается на наследие Евклида, описывающее свойства плоских и пространственных объектов. Эта модель построена для идеализированных фигур, таких как прямые линии и правильные многоугольники, которые редко встречаются в природе. Однако именно такие формы доминируют в среде, созданной человеческими руками: в архитектуре, машиностроении и бытовой инфраструктуре. Поэтому законы евклидовой геометрии становятся универсальным инструментом для проектирования и описания искусственных объектов неживой материи. В итоге мы видим, что школьная программа идеально адаптирована для познания того упорядоченного мира, который человек сконструировал вокруг себя. Но она не подходит для описания природы. Природа устроена иначе: в ней нет идеальных ровных фигур, гладких поверхностей, строгих прямых углов. Для более точного описания природного мира была создана Фрактальная геометрия.

Сейчас фракталы находят применение в таких разных сферах, как естественные науки, современные технологии и цифровое искусство. Их принципы используются в архитектурном проектировании, финансовом моделировании, медицине, инженерии, биологии и компьютерной графике. Например, на принципе самоподобия основано целое направление в компьютерной графике. При таком подходе компьютер хранит не готовый объект, а лишь формулу его отрисовки, что значительно экономит память. Принципы построения фракталов используются в различных разделах физики для описания процессов или объектов обладающих высокой структурной сложностью. Одно из самых заметных изобретений в этой области — фрактальная антенна, которая была разработана американским инженером Натаном Коэном в 1995 году. Главное преимущество такой антенны заключается в её широком диапазоне рабочих частот. А ещё она занимает намного меньший размер, чем аналоги классической формы, и может выступать в качестве основы для подводных антенн. Фрактальные принципы также используются для анализа нерегулярных структур данных (фрактальный анализ), что используется в обработке сигналов, анализе экономических процессов. Многие объекты в природе обладают свойствами фрактала, например: побережья, облака, кроны деревьев, снежинки, брокколи, система кровообращения, альвеолы, что используется для моделирования природных явлений. Таким образом мы понимаем, что современная наука для более точного описания требует работы с фрактальной геометрией.

Цель: Изучение алгоритмов построения фракталов с помощью геометрических преобразований плоскости и создание программы для визуализации фрактальных кривых.

Задачи:

  • Изучение видов фракталов и способов их построения.

  • Изучение аффинных преобразований плоскости.

  • Изучение свойств тригонометрических функций

  • Создание программы для визуализации фрактальных кривых.

История фракталов

Фрактал (лат. fractus — дроблёный, разбитый, состоящий из элементов) — множество, обладающее свойством самоподобия (объект, в точности или приближённо совпадающий с частью себя самого, то есть целое имеет ту же форму, что и одна или более частей). В математике под фракталами понимают множества точек в евклидовом пространстве, имеющие дробную метрическую размерность (в смысле Минковского или Хаусдорфа), либо метрическую размерность, отличную от топологической, поэтому их следует отличать от прочих геометрических фигур, ограниченных конечным числом звеньев. Самоподобные фигуры, повторяющиеся конечное число раз, называются предфракталами.

Первые примеры самоподобных множеств с необычными свойствами появились в XIX веке в результате изучения непрерывных не дифференцируемых функций (например, функция Больцано, функция Вейерштрасса, множество Кантора). В 1872 году Карл Вейерштрасспредставил пример функции, непрерывной всюду, но нигде не дифференцируемой. Её график был настолько «изломанным», что не имел касательной ни в одной точке. Термин «фрактал» был позднее введён польским математиком Бенуа Мандельбротом, однако о концепции фракталов было известно задолго до его первых работ.

Первую такую фигуру, которая вошла в историю как «множество Кантора», открыл Георг Кантор в 1883 году. Он взял отрезок и разделил его на три части, среднюю выбросил, после чего остались два крайних отрезка. «Ему открылась удивительная картина: если совершить это действие бесконечное число раз, то возникнет бесконечное множество линий. В каждой из этих линий будет заключаться бесконечное множество точек. Так он понял, что столкнулся с величиной, которая больше, чем бесконечность». На её основе математик продемонстрировал и самоподобие, и рекурсию.

В 1870-1880-х годах Георг Кантор доказал равную мощность отрезка[0,1] и квадрата [0,1]x[0,1]. Казался невозможным факт того, что одномерный объект может содержать ровно столько же точек, сколько двумерный. Математики сомневались в том, можно ли сделать непрерывное отображение, заполняющее квадрат. В 1890 году вышла короткая статья итальянского математика Пеано «О кривой, которая заполняет всю плоскую область». В статье не было изображения кривой — Пеано хотел строгого доказательства без опоры на рисунки. Он дал явное аналитическое определение двух функций f(x) и g(x), где (f(x),g(x)) пробегает по всем точкам единичного квадрата.

В 1904 году шведский математик Хельге фон Кох (Helge von Koch) захотел сделать то же что и Карл Вейерштрасс, но геометрически просто и наглядно, он создал кривую, позднее названную его именем. Хельге фон Кох опубликовал статью «О непрерывной кривой без касательной, получаемой с помощью элементарного геометрического построения», в которой впервые описал эту необычную линию. Она имела парадоксальные свойства: имела бесконечную, не возможную для измерения длину, но ограничивала конечную, вполне измеримую площадь.

Польский математик Вацлав Серпинский искал пример Канторовой кривой — кривой, которая разветвляется в каждой своей точке. Он нашел его в виде фигуры, которая позднее стала называться треугольником Серпинского. В 1915 году он опубликовал статью «О кривой, каждая точка которой является точкой ветвления». На следующий год он обобщил свою идею на квадрат.

В 1918 году французский математик Гастон Морис Жюлиа написал 199-страничный «Мемуар об итерации рациональных функций», который мгновенно принес ему славу. Жюлиа исследовал, что происходит к бесконечному повторению применения одной и той же функции к точке в комплексной плоскости. Если взять точки, чьи орбиты остаются ограниченными на протяжении всех итераций, то получится множество Жюлиа. Жюлиа доказал, что для большинства рациональных функций это множество будет бесконечно. Параллельно с ним работал Пьер Жозеф Луи Фату. Они с Жюлиа приходили к одним и тем же открытиям в 1917-1919 годах. В 1920 году Фату опубликовал свой 280-страничный мемуар.

В 1934 году американский инженер и финансовый аналитик Ральф Нельсон Эллиот выдвинул свою «Теорию волн» после 4 лет исследования фондового рынка. Он заметил закономерности в движении цен на рынке. Эти модели повторяются, формируя большие и меньшие версия самих себя - «Волны». Нельсон не связывал свою теорию с фракталами, но сделал предположение, что эти модели самоподобны. В 1946 году он выпустил свою итоговую работу «Закон природы: секрет Вселенной».

Все эти фигуры бросили вызов классическому математическому анализу и подтолкнули математиков на более глубокое изучение самоподобных фигур.

Бенуа Мандельброт вел термин «фрактал» в 1975 году. За основу он взял латинское слово fractus, означающее «разделённый на части». Мандельброт всю жизнь интересовался «грубостью» и нерегулярностью мира: формы крон деревьев, облаков, кровеносные сосуды. Обычные, евклидовы фигуры были неспособны описать всю сложность природы, ведь в природе не существует прямых линий, треугольников, квадратов кругов и так далее.

В 1967 году он опубликовал статью «Какова длина побережья Великобритании?». Он заметил парадокс: чем точнее измеряешь берег, тем длиннее он становится. Если брать более короткую «линейку» каждый раз, то длинна берега будет увеличиваться до бесконечности! Все из-за того, что берег — это не гладкая линия, а более сложная самоподобная структура.

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

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

Виды фракталов

Можно выделить несколько видов фракталов:

1. Геометрические фракталы.

Строятся путем итеративного повторения простой геометрической процедуры (рис 1). Рекурсивный метод — самый наглядный способ построения геометрических фракталов, он состоит из трех обязательных шагов:

  • Инициатор — задается начальная геометрическая фигура (отрезок, равносторонний треугольник, квадрат и т.п.)

  • Генератор — определяется фиксированное правило замены: каждый исходный элемент (инициатор) заменяется на конечный набор из уменьшенных, повернутых и сдвинутых копий инициатора.

  • Рекурсивное применение — на каждом шаге каждый экземпляр инициатора заменяется масштабированной копией генератора с учетом ориентации.

Рис 1

2. Алгебраические фракталы.

Это фракталы, который строятся на основе алгебраических формул. Такие фракталы создаются с помощью математических формул, которые применяются к координатам точек, например множество Мандельброта (рис 2) и множество Жюлиа (рис 3).

Рис 2 Рис 3

3. Стохастические фракталы

Стохастические (случайные) фракталы — это фракталы, в построении которых присутствует элемент случайности. Стохастические фракталы образуются, если в итерационной системе случайным образом изменяются один или несколько параметров (траектория Броуновского движения, рис 4). При этом ключевое свойство самоподобия сохраняется, но проявляется в статистическом смысле — части объекта похожи на целое не точно, а с определенной степенью вероятности (папоротник Барнсли, рис 5).

Рис 5 Рис 6

Способы построения фракталов

  1. Системыитерируемыхфункций (Iterated Functions Systems)

Система Итерируемых Функций (Iterated Functions System, IFS) — это конечный набор сжимающих отображений (контракций), заданных на полном метрическом пространстве (обычно ℝ2).

Метрическое пространство (X, d) — это множество точек X с метрикой d.

Метрикой называют функцию расстояния d(a,b), удовлетворяющую четырем свойствам:

  • Неотрицательной и вещественнозначность: d(a,b) ∈ [0, +∞)

  • Симметричность: d(a,b) = d(x,b)

  • Неравенство треугольника: d(a,b) > d(a,c) + d(b,c)

  • Равенство нулю: d(a,b) = 0 ⇔ a = b

Отображение плоскости(Аффинное преобразование) называют сжимающим если существует такой коэффициент сжатия Sn, что для любых двух точек a,b ∈ X выполняется

Зачастую рассматривается равномерно сжимающая система итерируемых функций, для которой существует общее число S, такое что для любого i.

Аттрактором IFS называют такое единственное множество A, для которого выполняется A = F(A), где F(A) – это оператор Хатчинсона - . Аттрактор и является конечным фракталом.

  1. L-системы

L-системы(системы Линденмайера) - это инструмент для моделирования роста биологических структур и генерации геометрических фракталов, придуманные в 1968 году венгерским биологом Аристидом Линденмайером для описания развития клеток растений. Позже их стали активно использовать в компьютерной графике для создания фракталов и реалистичных растений.

Система Линденмайера — это система перезаписи строк параллельного типа, предназначенная для моделирования роста (в первую очередь биологических структур).

L-система задается кортежом(упорядоченной четверкой), где:

  • V – конечный непустой алфавит (множество символов.)

  • – аксиома (исходная строка)

  • P – конечное множество продукций (правила переписывания). Каждая продукция имеет вид a → χ, где , .

  • → – отношение переписывания

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

  • F – Переместиться вперед и нарисовать линию

  • f – Переместиться вперед

  • + – Повернуть налево на угол δ

  • - – повернуть направо на угол δ

  • [ – сохранить текущее состояние

  • ] – восстановить предыдущее состояние

Как строится фрактал:

  1. Берется аксиома

  2. На каждой итерации аксиома заменяется по правилам перезаписи

  3. Строка интерпретируется как команды для черепахи

3) Фракталы на основе методов Escape-Time

Метод Escape Time – это самый простой и самый популярный способ генерации алгебраических фракталов.

Для каждой точки на комплексной плоскости строится последовательность:

z0

z1 = f(z0)

z2 = f(z1)

...

zn = f(zn-1)

Считается количество итераций n, пока не выполняется условие |zn| > Rescape.

Если за максимальное количество итераций точка zn не выходит за пределы круга радиусом Rescape, то точка считается принадлежащей к фракталу и закрашивается черным.

Если точка вышла за пределы круга на итерации k, то цвет зависит от k.

Аффинные преобразования плоскости

Аффи́нное преобразование (от лат. affinis «соприкасающийся, близкий, смежный») — отображение плоскости или пространства в себя, при котором параллельные прямые переходят в параллельные прямые, пересекающиеся — в пересекающиеся, скрещивающиеся — в скрещивающиеся.

Примерами аффинных преобразований являются

  • движения;

  • растяжения;

  • преобразования подобия

  • повороты.

  1. Параллельный перенос.

Перенос является частным случаем аффинного преобразования и частным случаем движения, он сохраняет абсолютно все метрические и геометрические свойства фигур:

  • Сохраняет длины отрезков |A'B'| = |AB|

  • Сохраняет углы между прямыми ∠A'B'C' = ∠ABC

  • Сохраняет направления векторов

Задается вектором переноса
Если точка A имела координаты (x, y), то её образ A' после переноса имеет координаты:

  1. Масштабирование

Масштабирование(гомогетия) — это преобразование, которое увеличивает или уменьшает все расстояния от неподвижной точки (центра) в одно и то же число раз, сохраняя форму и углы, но изменяя размеры.

  • Сохраняет углы между прямыми. ∠A'B'C' = ∠ABC

  • Сохраняет направления векторов.

  • Не сохраняет длины отрезков. Все расстояния умножаются на коэффициент масштабирования k.

  1. Относительно начала координат:

  1. Относительно произвольного центра :

Особый случай k = -1 — это центральная симметрия относительно точки C

Виды масштабирования:

  • Равномерное — коэффициент одинаков по всем осям

  • Неравномерное (растяжение/сжатие вдоль осей):

3. Поворот

Поворот (вращение) плоскости — это преобразование, при котором все точки поворачиваются на один и тот же угол вокруг неподвижной точки (центра поворота), сохраняя расстояния и форму:

  • Сохраняет длины отрезков |A'B'| = |AB|

  • Сохраняет углы между прямыми ∠A'B'C' = ∠ABC

  • Не сохраняет направления векторов

  1. Относительно начала координат (поворот на угол φ):

  1. Относительно произвольного центра :

4.Центральная симметрия

Центральная симметрия — это отражение относительно точки C.

  • Сохраняет длины отрезков |A'B'| = |AB|

  • Сохраняет углы между прямыми ∠A'B'C' = ∠ABC

  • Не сохраняет направления векторов

  1. Относительно начала координат:

  1. Относительно произвольного центра :

Рассмотрим построение кривой Коха(рис 7) с использованием аффинных
преобразований:

Рис. 7

Инициатором для кривой Коха является отрезок [(0,0),(1,0)], а генератором набор преобразований:

  • f1:

  • f2:

  • f3:

  • f4:

При выполнении преобразований на первой итерации(рис 8):

  • f1: Точка перейдет в ; - в

  • f2: Точка перейдет в ; - в

  • f3: Точка перейдет в ; - в

  • f4: Точка перейдет в ; - в

(
Рис. 8)

При увеличении количества итераций фигура будет становиться более сложной(рис 9):


 

Рис. 9

Практическая часть

Для визуализации фракталов была создана программа. При запуске программы открывается окно создания генератора фрактала (рис 10). Пользователь может выбрать некоторое количество точек. Если пользователь введет меньше трех точек, то покажется окно с предупреждением (рис 11).

Р
ис. 10 Рис. 11

При нажатии на кнопку «Сохранить», координаты точек сохраняются в динамическом списке. Затем из координат каждой точки вычитаются координаты первой точки, чтобы первая точка списка совпадала с началом координат. Вычисляется угол rotateAngle между осью Ox и отрезком, который образуют первая и последняя точка в списке: , где (x,y) – первая точка списка (x0,y0) — последняя точка списка. Затем все точки в списке поворачиваются вокруг точки (0,0) на угол, противоположный углу rotateAngle, чтобы расположить отрезок образованный первой и последней точками фрактала параллельно горизонтальной оси.

Открывается окно отрисовки фрактала(рис 12).

Рис. 12

По нажатию на кнопку «Отрисовать» создается исходный список — копия генератора. Затем итеративно в цикле «наращивается» фрактал: каждая пара последовательных точек исходного списка заменяется на измененную копию генератора. Количество итераций можно изменять. Генератор изменяется по следующему принципу:

  1. Вычисляется коэффициент масштабирования: , угол поворота и вектор параллельного переноса , где (xi, yi) – координаты первой точки в паре, (xi+1, yi+1) — координаты второй точки в паре, (X0, Y0) – первая точка генератора, (X, Y) — последняя точка генератора.

  2. К каждой точке генератора применяется формула:

в ней выражение в скобках осуществляет поворот точки вокруг точки (0,0), домножение на k – масштабирование, а прибавление vx и vy – сдвиг на vx по горизонтали и на vy по вертикали.

Когда все итерации в цикле пройдены, конечный список точек отрисовывается в виде ломанной (рис 13, 3 итерации):

Рис. 13

Таким образом данная программа позволяет строить любые фрактальные кривые по заданной исходной ломаной.

Заключение

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

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

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

Список литературы

  1. Секованов В. С. Элементы теории фрактальных множеств: Учеб. пособие.- Кострома: КГУ им. Н. А. Некрасова, 2005.-135 с.

  2. Глейк Д. Хаос. Создание новой науки / Д. Глейк. – М. : Амфора, 2001. – 398 с.

  3. Заславский А.А. Геометрические преобразования / А.А. Заславский. – 2-е изд. – М. : МЦНМО, 2004. – 86с.

  4. Мандельброт Б. Фрактальная геометрия природы / Б. Мандельброт. – М. : Институт компьютерных исследований, 2002. – 666 с.

  5. Морозов А.Д. Введение в теорию фракталов / А.Д. Морозов. – М. : Институт компьютерных исследований, 2002. – 160 с.

  6. Самарский А.А. Компьютеры и нелинейные явления: Информатика и современное естествознание / Авт. Предисл. А.А. Самарский. – М.: Наука, 1988. – 192с. ил. – (Серия «Кибернетика – неограниченные возможности и возможные ограничения»).

  7. Федер Е. Фракталы. пер. с англ. / Е. Федер. – М. : Мир, 1991. – 143 с.

  8. Яглом И.М. Геометрические преобразования Т.2 / И.М. Яглом – М.: Гостехиздат, 1956. – 611с.

  9. Шредер М. Фракталы, хаос, степенные законы./ М. Шредер – Ижевск : НИЦ «Регулярная и хаотическая динамика», 2001. – 528с.

Приложение

Листинг программы

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace Fractals

{

publicpartialclassucMain : UserControl

{

privatereadonlyFormContainer mainForm;

internalList<PointF> pattern = [];

privatePointF[] pointsToDraw;

publicucMain(FormContainerformContainer)

{

InitializeComponent();

mainForm = formContainer;

pictureBox1.Paint += pictureBox1_Paint;

button1.Click += button1_Click;

button2.Click += button2_Click;

}

privatevoidpictureBox1_Paint(objectsender, PaintEventArgse)

{

Graphicsg = e.Graphics;

g.Clear(pictureBox1.BackColor);

if (pointsToDraw != null)

{

using (Penpen = newPen(Color.Black, 2))

{

g.DrawLines(pen, pointsToDraw);

}

}

}

privatevoidbutton1_Click(objectsender, EventArgse)

{

floatwindowWidth = pictureBox1.Size.Width * 0.6f;

floatgeneratorWidth = pattern[pattern.Count - 1].X - pattern[0].X;

floatsize = MathF.Abs(windowWidth / generatorWidth);

newFractal(pattern).Draw((int)numericUpDown1.Value, newPointF((pictureBox1.Size.Width - generatorWidth*size)/2f, pictureBox1.Size.Height/ 2f), size, 0, (points) => { pointsToDraw = points.ToArray(); });

pictureBox1.Invalidate();

}

privatevoidbutton2_Click(objectsender, EventArgse)

{

mainForm.ShowControl(newucPatternCreator(mainForm));

}

}

}

using FractalTest.OtherUtils;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace Fractals

{

publicpartialclassucPatternCreator : UserControl

{

privatereadonlyFormContainer mainForm;

privatereadonlyfloat cellSize;

privatereadonlyfloat correctEdgesDictance;

privatereadonlyList<PointF> selectedPoints = [];

publicucPatternCreator(FormContainerformContainer)

{

InitializeComponent();

mainForm = formContainer;

cellSize = 30f;

correctEdgesDictance = 500f;

pictureBox1.Paint += pictureBox1_Paint;

pictureBox1.MouseClick += pictureBox1_MouseClick;

button2.Click += button2_Click;

}

privatevoidpictureBox1_Paint(objectsender, PaintEventArgse)

{

Graphicsg = e.Graphics;

g.Clear(pictureBox1.BackColor);

intwidth = pictureBox1.Size.Width;

intheight = pictureBox1.Size.Height;

intpointRadius = 4;

using (Brushbrush = newSolidBrush(Color.Gray))

using (PengridPen = newPen(Color.LightGray))

using (PenlinesPen = newPen(Color.LightGray, 3))

{

for (floatx = 0; x < width; x += cellSize)

{

g.DrawLine(gridPen, x, 0, x, height);

}

for (floaty = 0; y < height; y += cellSize)

{

g.DrawLine(gridPen, 0, y, width, y);

}

if (selectedPoints.Count > 1)

{

g.DrawLines(linesPen, selectedPoints.ToArray());

}

foreach (PointFpointin selectedPoints)

{

g.FillEllipse(brush, point.X - pointRadius, point.Y - pointRadius, pointRadius * 2, pointRadius * 2);

}

}

;

}

privatevoidpictureBox1_MouseClick(objectsender, MouseEventArgse)

{

floatx = MathF.Round(e.X/cellSize) * cellSize;

floaty = MathF.Round(e.Y / cellSize) * cellSize;

PointFclickPoint = newPointF(x, y);

if (selectedPoints.Contains(clickPoint))

{

selectedPoints.Remove(clickPoint);

}

else

{

selectedPoints.Add(clickPoint);

}

pictureBox1.Invalidate();

}

privatevoidbutton2_Click(objectsender, EventArgse)

{

if (selectedPoints.Count < 3)

{

MessageBox.Show("Выберитехотябы 3 точки", "Предупреждение", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

SizeFstartPoint = newSizeF(selectedPoints[0]);

floatdx = selectedPoints[^1].X - selectedPoints[0].X;

floatdy = selectedPoints[^1].Y - selectedPoints[0].Y;

floatedgesDistance = MathF.Sqrt(dx * dx + dy * dy);

floatrotateAngle = -MathF.Atan2(selectedPoints[^1].Y - selectedPoints[0].Y, selectedPoints[^1].X - selectedPoints[0].X);

for (inti = 0; i < selectedPoints.Count; i++)

{

selectedPoints[i] = selectedPoints[i] -startPoint;

selectedPoints[i] = newPointF(selectedPoints[i].X * correctEdgesDictance / edgesDistance, selectedPoints[i].Y * correctEdgesDictance / edgesDistance);

floatnewX = (float)(selectedPoints[i].X * Math.Cos(rotateAngle) - selectedPoints[i].Y * Math.Sin(rotateAngle));

floatnewY = (float)(selectedPoints[i].Y * Math.Cos(rotateAngle) + selectedPoints[i].X * Math.Sin(rotateAngle));

selectedPoints[i] = newPointF(newX, newY);

}

ucMainform = newucMain(mainForm);

form.pattern = selectedPoints;

mainForm.ShowControl(form);

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using FractalTest.OtherUtils;

namespace Fractalss

{

internalclassFractal(List<PointF> generator)

{

privatereadonly List<PointF> pattern = generator;

publicvoidDraw(intnumberOfIterations, PointF center, floatsize, doublealpha, Action<PointF[]> action)

{

List<PointF> points = [.. pattern];

points.Multiply(100);

for (inti = 0; i < numberOfIterations - 1; i++)

{

BuildUpPattern(ref points);

}

points.Multiply(0.01f);

action(TransformPatternByParams(points, center, size, alpha).ToArray());

}

privatevoidBuildUpPattern(refList<PointF> points)

{

vartoReturn = newList<PointF>();

for(inti = 0; i < points.Count - 1; i++)

{

floatsize = MathF.Sqrt(MathF.Pow(points[i].X - points[i + 1].X, 2) + MathF.Pow(points[i].Y - points[i + 1].Y, 2)) /

MathF.Sqrt(MathF.Pow(pattern[0].X - pattern[^1].X, 2) + MathF.Pow(pattern[0].Y - pattern[^1].Y, 2));

doublealpha;

alpha = Math.Atan2(points[i + 1].Y - points[i].Y, points[i + 1].X - points[i].X);

vartransformed = TransformPatternByParams(pattern, points[i], size, alpha);

transformed.RemoveAt(transformed.Count - 1);

toReturn.AddRange(transformed);

}

toReturn.Add(points[^1]);

points = toReturn;

}

privatestaticList<PointF> TransformPatternByParams(List<PointF> points, PointFcenter, floatsize, doublealpha)

{

List<PointF> transformedPoints = [];

foreach (PointFpointinpoints)

{

floatnewX = (float)(point.X * Math.Cos(alpha) - point.Y * Math.Sin(alpha));

floatnewY = (float)(point.Y * Math.Cos(alpha) + point.X * Math.Sin(alpha));

newX *= size;

newY *= size;

newX += center.X;

newY += center.Y;

transformedPoints.Add(newPointF(newX, newY));

}

returntransformedPoints;

}

}

}

namespace Fractals

{

internalstaticclassProgram

{

///<summary>

/// The main entry point for the application.

///</summary>

[STAThread]

staticvoidMain()

{

ApplicationConfiguration.Initialize();

Application.Run(newFormContainer());

}

}

}

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace Fractals

{

publicpartialclassFormContainer : Form

{

privateUserControl currentControl = null;

publicFormContainer()

{

InitializeComponent();

this.Text = "Fractals";

ShowControl(newucPatternCreator(this));

}

internalvoidShowControl(UserControlnewControl)

{

if (currentControl != null)

{

panelContent.Controls.Remove(currentControl);

currentControl.Dispose();

currentControl = null;

}

newControl.Dock = DockStyle.Fill;

panelContent.Controls.Add(newControl);

currentControl = newControl;

}

}

}

Просмотров работы: 0