Z czym kojarzy nam się matematyka? Większość z nas ma niezbyt przyjemne wspomnienia ze szkoły. Przecież funkcja liniowa czy kwadratowa nie przyda się nam w życiu codziennym. Kto choć raz użył algebry, gdy gotował obiad? Może jedynie geometria przyda się architektom. Warto jednak spojrzeć na matematykę inaczej. Potrafi ona zachwycić swoim pięknem nie tylko matematyków, ale również humanistów czy artystów. Trudno jest zmienić myślenie o tym przedmiocie szkolnym, dlatego chciałbym pokazać ukryte piękno matematyki – fraktale.

Czym jest fraktal? Polska wersja Wikipedii podaje, że pojęcie to oznacza zwykle obiekt samo-podobny (tzn. taki, którego części są podobne do całości) albo „nieskończenie subtelny” (ukazujący subtelne detale nawet w wielokrotnym powiększeniu). Nawiasem mówiąc, kto z nas słyszał, żeby definicja matematyczna zawierała słowa nieskończenie subtelny? Co ta definicja oznacza w praktyce? Przyjrzyjmy się jednemu z najbardziej znanych fraktali: zbiorowi Mandelbrota.

Rys . 1. Zbiór Mandelbrota w pełnej okazałości.

Rys . 1. Zbiór Mandelbrota w pełnej okazałości.

Zbiór Mandelbrota często jest nazywany żuczkiem. Wystarczy spojrzeć na rys. 1., żeby zrozumieć dlaczego. Teraz zerkinijmy na rys. 2. Jest to przybliżenie czółki naszego owada. Z łatwością możemy rozpoznać tam kolejne mniejsze żuczki. To jest właśnie samo-podobieństwo fraktali. Nie ważne jak bardzo byśmy powiększali fraktal, zawsze dostrzeżemy podobieństwo do całego obiektu.
Nic nie stoi również na przeszkodzie, aby trochę inaczej pokolorować naszego żuczka. Obrazuje to rys. 3. To również jest przybliżenie innego fragmentu całego obrazu.

Rys. 2. Przybliżony fragment zbioru Mandelbrota.

Rys. 2. Przybliżony fragment zbioru Mandelbrota.

Rys. 3. Kolorowy fragment zbioru Mandelbrota.

Rys. 3. Kolorowy fragment zbioru Mandelbrota.

Ale jaki jest związek zbioru Mandelbrota z matematyką? Przecież to jest obraz, a matematyka to zwykłe liczby. Otórz ten niesamowicie skomplikowany kształt uzyskujemy bardzo prostym wzorem matematycznym. Jedyną trudnością jest to, że trzeba operować na liczbach zespolonych.
Czym zatem są liczby zespolone? W skrócie rzecz ujmując, możemy potraktować liczbę zespoloną jako punkt na płaszczyźnie. Zatem, jak każdy punkt w układzie współrzędnych, liczba zespolona posiada dwie składowe tzw. część rzeczywistą i urojoną. Dociekanie skąd się wzięły takie nazwy pozostawiam czytelnikowi. Nam potrzebna będzie jedynie definicja podstawowych operacji na liczbach zespolonych.

Liczbę zespoloną będziemy oznaczali za pomocą litery z, zaś jej składowe będziemy zapisywali jako z = [r, i]. Przyjmijmy zatem, że mamy dwie liczby zepolone z1 = [r1, i1] oraz z2 = [r2, i2]. Poszczególne operacje będą wyglądały następująco:

  • z1 + z2 = [r1 + r2, i1 + i2]

  • z1 z2 = [r1r2 – i1i2, i1r2 + r1i2]

  • |z| = sqrt(r2 + i2)

Skoro już wiemy czym są liczby zespolone i jak przeprowadzać podstawowe operacje, pora zapoznać się z długo oczekiwanym wzorem na zbiór Mandelbrota. Jest to wzór rekurencyjny, czyli obliczanie kolejnych wartości wymaga znajomości poprzednich. Sam wzór jest prosty:

z0 = 0

zn+1 = zn2 + p

Powyższy zapis oznacza, że pierwszą liczbą zespoloną jest liczba zero czyli z0 = [0, 0]. Każdą kolejną tworzymy poprzez podniesienie do potęgi poprzedniej liczby i dodanie pewnej stałej p, która również jest liczbą zespoloną.
No dobrze, ale jak to się przekłada na ten niesamowity kształt żuczka? Wystarczy ten wzór zastosować dla każdego piksela ekranu. Wtedy stałą p będą współrzędne tego piksela. Kolor na jaki pomalujemy nasz piksel zależy od tego, jak szybko moduł liczby zprzekroczy 2. Im szybciej przekroczymy tę wartość tym ciemniejszy będzie kolor piksela. W zapisie matematycznym warunek ten wygląda następująco:

|zn| < 2
Trzeba tylko pamiętać, że dla niektórych pikseli |znnigdy nie przekroczy wartości 2, dlatego, gdy n osiągnie pewną wartość, powinniśmy przerwać obliczenia uznając dla uproszczenia, że dla tego punktu nigdy nie przekroczymy tej wartości. Przy jak wysokim n powinniśmy przerwać obliczenia? To zależy od mocy obliczeniowej komputera. Zdradzę tylko, że jeśli przyjmiemy, że n <= 100, to otrzymamy zadowalające rezultaty.
Zbiór Mandelbrota to nie jedyny fraktal, który możemy otrzymać tą prostą metodą. Wprowadzając pewne modyfikacje do tego zbioru otrzymamy np. płonący statek, drapieżnego ptaka, czy zbiur Julii (rys. 5.)

Rys. 5. Różne zbiory Julii

Rys. 5. Różne zbiory Julii

Jakiś czas temu postanowiłem zaimplementować najpopularniejsze fraktale. Stworzyłem w tym celu niewielki projekt, który jest dostępny na GitHubie Początkowo program obliczał kolor poszczególnych pikseli na procesorze. Wyrysowanie obrazu 800×600 pikseli zajmowało mniej więcej 0,5 s. Chciałem jednak mieć możliwość oglądania różnych fragmentów fraktali w wybranej skali. Okazało się zatem, że pół sekundy to zbyt długi czas i trudno było manipulować fraktalem.

Postanowiłem zatem wykorzystać bibliotekę OpenGL. Mój pomysł polegał na tym, żeby na całym dostępnym obrazie wyświetlić jeden prostokąt. Każdemu z wierzchołków tego prostokąta przypisałem współrzędne jakie one reprezentują na płaszczyźnie liczb zespolonych. Natomiast wszystkie obliczenia wykonywane były we fragment shaderze. Kod tego shadera dla zbioru Mandelbrota znajduje się poniżej. Przejście na OpenGL spowodowało, że uzyskiwany przeze mnie obraz fraktala odbywał się już w czasie rzeczywistym.

Dodawanie kolejnych fraktali było już łatwe. Wystarczyło napisać nowy fragment shader, a właściwie podmienić wzór na obliczanie koloru piksela.

Fraktale moża rówinież tworzyć na kilka innych sposobów. Myślę jednak, że powyższe przykłady wystarczą, aby zachęcić do samodzielnego odkrywania fraktali i innych ciekawostek ze świata matematyki.


Nawigacja