Як запрограмувати фрактал?


77

У мене немає досвіду програмування фракталів. Звичайно, я бачив знамениті образи Мандельброта та подібні.

Чи можете ви надати мені прості алгоритми фракталів?

Мова програмування насправді не має значення, але мені найбільше відомі ActionScript, C #, Java.

Я знаю, що якщо я гуглю фрактали, я отримую багато (складної) інформації, але я хотів би почати з простого алгоритму і пограти з ним.

Також вітаються пропозиції щодо вдосконалення базового алгоритму, наприклад, як зробити їх у цих чудових кольорах тощо.


6
На основі відповідей у ​​цьому питанні я створив суть на github з анімованим мандельбротом у javascript, використовуючи елемент canvas. gist.github.com/1853604
Sander Versluys

Відповіді:


58

Програмувати Мандельброта просто.
Мій швидкий-брудний код знаходиться нижче (не гарантується, що він не містить помилок, але хороший контур).

Ось контур: Набір Мандельброта лежить у Комплексній сітці повністю в межах кола радіусом 2.

Отже, почніть із сканування кожної точки в цій прямокутній області. Кожна точка представляє комплексне число (x + yi). Ітерація цього комплексного числа:

[new value] = [old-value]^2 + [original-value] відстежуючи дві речі:

1.) кількість ітерацій

2.) відстань [нового значення] від початку.

Якщо ви досягли максимальної кількості ітерацій, все готово. Якщо відстань від початку координат більше 2, ви закінчили.

Завершивши, розфарбуйте оригінальний піксель залежно від кількості виконаних вами ітерацій. Потім перейдіть до наступного пікселя.

public void MBrot()
{
    float epsilon = 0.0001; // The step size across the X and Y axis
    float x;
    float y;
    int maxIterations = 10; // increasing this will give you a more detailed fractal
    int maxColors = 256; // Change as appropriate for your display.

    Complex Z;
    Complex C;
    int iterations;
    for(x=-2; x<=2; x+= epsilon)
    {
        for(y=-2; y<=2; y+= epsilon)
        {
            iterations = 0;
            C = new Complex(x, y);
            Z = new Complex(0,0);
            while(Complex.Abs(Z) < 2 && iterations < maxIterations)
            {
                Z = Z*Z + C;
                iterations++;
            }
            Screen.Plot(x,y, iterations % maxColors); //depending on the number of iterations, color a pixel.
        }
    }
}

Деякі деталі, які залишились поза увагою:

1.) Дізнайтеся, що саме являє собою квадрат комплексного числа і як його обчислити.

2.) З’ясуйте, як перевести (-2,2) прямокутну область на координати екрана.


29

Вам справді слід почати з набору Мандельброта і зрозуміти, що це насправді.

Ідея цього відносно проста. Ви починаєте з функції комплексної змінної

f (z) = z 2 + C

де z - комплексна змінна, а C - комплексна постійна . Тепер ви виконуєте ітерацію, починаючи з z = 0, тобто обчислюєте z 1 = f (0), z 2 = f (z 1 ), z 3 = f (z 2 ) тощо. Сукупність тих констант С, для яких послідовність z 1 , z 2 , z 3 , ... обмежена , тобто вона не йде до нескінченності, є набір Мандельброта (чорний набір на малюнку на сторінці Вікіпедії).

На практиці, щоб намалювати набір Мандельброта, слід:

  • Виберіть прямокутник у комплексній площині (скажімо, від точки -2-2i до точки 2 + 2i).
  • Покрийте прямокутник відповідною прямокутною сіткою точок (скажімо, 400x400 точок), яка буде відображена у пікселі на моніторі.
  • Для кожної точки / пікселя нехай C є цією точкою, обчисліть, скажімо, 20 доданків відповідної повторюваної послідовності z 1 , z 2 , z 3 , ... і перевірте, чи "вона переходить у нескінченність". На практиці ви можете під час ітерації перевірити, чи абсолютне значення одного з 20 термінів перевищує 2 (якщо один із цих термінів це робить, наступні умови гарантовано будуть необмеженими). Якщо якийсь z_k це робить, послідовність "йде до нескінченності"; в іншому випадку ви можете вважати це обмеженим.
  • Якщо послідовність, що відповідає певній точці C, обмежена, намалюйте відповідний піксель на малюнку чорним кольором (адже він належить до набору Мандельброта). В іншому випадку намалюйте його іншим кольором. Якщо ви хочете розважитися і створити гарні сюжети, намалюйте його різними кольорами залежно від величини абс (20-й термін).

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

Насолоджуйтесь!


10

Якщо складні числа болять від головного болю, існує широкий спектр фракталів, які можна сформулювати за допомогою L-системи. Для цього потрібно взаємодіяти пару шарів, але кожен з них цікавий сам по собі.

Спочатку вам потрібна черепаха. Вперед, назад, вліво, вправо, ручкою вгору, ручкою вниз. Існує безліч цікавих фігур, які можна зробити із графікою черепахи, використовуючи геометрію черепахи, навіть без керування L-системою. Шукайте "Графіка LOGO" або "Графіка черепахи". Повна система LOGO насправді є середовищем програмування Lisp із використанням непрозорого кембриджського польського синтаксису. Але вам не потрібно заходити майже настільки далеко, щоб отримати гарні фотографії, використовуючи концепцію черепахи.

Тоді вам потрібен шар для виконання L-системи. L-системи пов'язані з пост-системами і Semi-Туя систем , і як віруси, вони осідлали кордон Тьюринга Повнота. Концепція - це переписування рядків . Це може бути реалізовано як макророзширення або набір процедур з додатковими елементами керування для обмеження рекурсії. Якщо використовується макророзширення (як у прикладі нижче), вам все одно знадобиться процедура, встановлена ​​для зіставлення символів з командами черепахи та процедура ітерації через рядок або масив для запуску кодованої програми черепахи. Для набору процедур з обмеженою рекурсією ( наприклад, ) ви вбудовуєте команди черепахи в процедури і або додаєте перевірки рівня рекурсії до кожної процедури, або відтворюєте їх на функцію обробника.

Ось приклад дерева Піфагора в постскриптумі з використанням макророзширення та дуже скороченого набору команд для черепахи. Деякі приклади в python та математиці див. У моїй програмі коду з гольфу .

ps l-система піфагора дерево luser-droog


Зображення було створено за допомогою описаної тут техніки, щоб поєднати короткий фрагмент коду з невеликою ілюстрацією.
luser droog

8

Існує чудова книга " Хаос і фрактали", яка містить простий приклад коду в кінці кожного розділу, який реалізує якийсь фрактал чи інший приклад. Давним-давно, коли я прочитав цю книгу, я перетворив кожну програму-зразки (на якомусь базовому діалекті) в аплет Java, який працює на веб-сторінці. Аплети тут: http://hewgill.com/chaos-and-fractals/

Одним із зразків є проста реалізація Мандельброта.


6

Ще одним чудовим фракталом для вивчення є фрактал „Трикутник Серпінського”.

В основному, намалюйте три кути трикутника (кращий рівносторонній, але будь-який трикутник буде працювати), а потім починайте точку P на одному з цих кутів. Перемістіть P навпіл до будь-якого з 3 кутів навмання і проведіть там точку. Знову посуньте P наполовину до будь-якого випадкового кута, намалюйте та повторіть.

Можна подумати, що випадковий рух створить випадковий результат, але насправді це не так.

Довідково: http://en.wikipedia.org/wiki/Sierpinski_triangle


2
Це справді основа IFS, яку можна розглядати як узагальнення методу, який ви описуєте.
Algorias

6

Трикутник Серпінського та крива Коха - це особливі типи полум'яних фракталів. Фрактали полум'я - це дуже узагальнений тип ітераційної системи функцій, оскільки вона використовує нелінійні функції.

Алгоритм для IFS: es такий:

Start with a random point.

Повторіть наступне багато разів (принаймні мільйон, залежно від кінцевого розміру зображення):

Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5. Plot the new point on the screen.

Якщо точка знаходиться поза екраном, замість цього виберіть навмання нову.

Якщо ви хочете приємних кольорів, нехай колір залежить від останнього використовуваного перетворення.


5

Я б почав з чогось простого, наприклад, Сніжинки Коха . Це простий процес взяти лінію і перетворити її, а потім повторити процес рекурсивно, поки він не буде виглядати акуратно.

Щось надзвичайно просте, наприклад, взяти 2 бали (лінія) та додати 3 бал (зробити кут), а потім повторити кожен новий створений розділ.

fractal(p0, p1){
    Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
    fractal(p0,Pmid);
    fractal(Pmid, p1);
}

5

Я думаю, ви не можете бачити фрактали як алгоритм чи щось для програмування. Фрактали - це поняття! Це математична концепція детального шаблону, що повторюється.

Тому ви можете створити фрактал різними способами, використовуючи різні підходи, як показано на малюнку нижче.

введіть тут опис зображення

Виберіть підхід, а потім дослідіть, як його реалізувати. Ці чотири приклади були реалізовані з використанням Marvin Framework . Вихідні коди доступні тут


3

Набір мандельброта генерується шляхом багаторазового оцінювання функції, поки вона не переповнюється (деяка визначена межа), а потім перевірки, скільки часу знадобилося для переповнення.

Псевдокод:

MAX_COUNT = 64 // if we haven't escaped to infinity after 64 iterations, 
               // then we're inside the mandelbrot set!!!

foreach (x-pixel)
  foreach (y-pixel)
    calculate x,y as mathematical coordinates from your pixel coordinates
    value = (x, y)
    count = 0
    while value.absolutevalue < 1 billion and count < MAX_COUNT
        value = value * value + (x, y)
        count = count + 1

    // the following should really be one statement, but I split it for clarity
    if count == MAX_COUNT 
        pixel_at (x-pixel, y-pixel) = BLACK
    else 
        pixel_at (x-pixel, y-pixel) = colors[count] // some color map. 

Примітки:

значення - це комплексне число. комплексне число (a + b i) має квадрат (a a-b * b + 2 * a b i). Вам доведеться використовувати складний тип або включити цей розрахунок у ваш цикл.


1
Ви впевнені у значенні value.absolutevalue <1 мільярд ??? Як тільки value.absolutevalue перевищує 2, воно "втече" і перейде в нескінченність. Тож вам потрібно протестувати лише 2, а не 1 мільярд.
abelenky

3

Ну, прості та графічно привабливі насправді не йдуть рука об руку. Якщо ви серйозно ставитесь до програмування фракталів, я пропоную ознайомитись з ітераційними функціональними системами та досягненнями, які вони отримали при їх отриманні.

http://flam3.com/flame_draves.pdf


3

Ось простий і зрозумілий код на Java для mandelbrot та інших прикладів фракталів

http://code.google.com/p/gaima/wiki/VLFImages

Просто завантажте BuildFractal.jar, щоб протестувати його на Java та запустіть команду:

java -Xmx1500M -jar BuildFractal.jar 1000 1000 за замовчуванням MANDELBROT

Вихідний код також можна безкоштовно завантажувати / досліджувати / редагувати / розширювати.


2

Ось код, який я написав для фракталу Мандельброта, використовуючи звичайний javascript та HTML.

Будемо сподіватися, що код легко зрозуміти.

Найскладнішою частиною є масштабування і переклад систем координат. Також складним є виготовлення райдужної палітри.

function mandel(x,y) {
  var a=0; var b=0;
  for (i = 0; i<250; ++i) {
    // Complex z = z^2 + c
    var t = a*a - b*b;
    b = 2*a*b;
    a = t;
    a = a + x;
    b = b + y;
    var m = a*a + b*b;
    if (m > 10)  return i;
  }
  return 250;
}

введіть тут опис зображення


Елегантний і примірний приклад. Дякуємо, що поділилися;)
blurryroots

1

Люди вище використовують пошук середніх точок для Сьерпінського та Коха, я набагато більше рекомендую копіювати фігури, масштабувати їх, а потім перекладати, щоб досягти ефекту "фрактальності". Псевдокод на Java для sierpinski виглядатиме приблизно так:

public ShapeObject transform(ShapeObject originalCurve)
    {
        Make a copy of the original curve
        Scale x and y to half of the original
        make a copy of the copied shape, and translate it to the right so it touches the first copied shape
        make a third shape that is a copy of the first copy, and translate it halfway between the first and second shape,and translate it up
        Group the 3 new shapes into one
        return the new shape
    }

1

Іноді я програмую фрактали для розваги та як виклик. Ви можете знайти їх тут . Код написаний на Javascript за допомогою бібліотеки P5.js і може бути прочитаний безпосередньо з вихідного коду HTML.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.