23/07/2026
Cześć,
Matematyka jest piękna, co możecie zobaczyć na poniższym filmiku. Przedstawia on 18 fraktali wygenerowanych za pomocą przekształceń afinicznych. Idea generowania jest taka:
1. Ustalamy ilość przekształceń dla fraktala (każde dane jest ustalonymi z góry wartościami A0, A1, A2, A3, B0, B1), oraz tyle samo współczynników prawdopodobieństw wylosowania danego przekształcenia.
2. Wyrysowujemy w pętli zadaną ilość punktów, np: 100000.
3. Ustalamy początkowy punkt na (x,y) = (SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
4. losujemy przekształcenie i wyliczamy współrzędne kolejnego punktu do wyrysowania:
TransformIndex = GetRandomTransformIndex;
x_next = Transforms[TransformIndex].A0 * x + Transforms[TransformIndex].A1 * y + Transforms[TransformIndex].B0;
y_next = Transforms[TransformIndex].A2 * x + Transforms[TransformIndex].A3 * y + Transforms[TransformIndex].B1;
5. Stawiamy wyliczony punkt:
PutPixel(x_next, y_next);
6. Aktualizujemy współrzędne x i y wyliczonym punktem, tak żeby kolejne wyliczenia były przeprowadzone z jego udziałem:
x = x_next;
y = y_next;
Poniżej zamieszczam też poglądowy fragment kodu użyty w programie do wygenerowania tego filmiku. Tam stosuję dodatkowo interpolację pomiędzy dwoma fraktalami, żeby uzyskać ładną animację przejścia między nimi. Dla zainteresowanych - jeśli chcesz uzyskać pełny kod źródłowy programu, pisz na priv.
void PutPixel(SDL_Surface* surface, int Index)
{
float xp, yp;
SDL_Color green{ 0x00, 0x99, 0x00, 0xff };
SDL_Color black = { 0x00, 0x00, 0x00, 0xff };
SDL_Color color;
float A0, A1, A2, A3, B0, B1, DeltaX, DeltaY, Scale;
float rand_number = SDL_randf() * 100.0f;
int TransformIndex{};
color = green;
for (size_t i = 0; i < Fractals[Index]->p.size(); ++i)
{
if (rand_number < Fractals[Index]->p[i])
{
TransformIndex = static_cast(i);
break;
}
}
A0 = Fractals[Index]->Transforms[TransformIndex].a[0];
A1 = Fractals[Index]->Transforms[TransformIndex].a[1];
A2 = Fractals[Index]->Transforms[TransformIndex].a[2];
A3 = Fractals[Index]->Transforms[TransformIndex].a[3];
B0 = Fractals[Index]->Transforms[TransformIndex].b[0];
B1 = Fractals[Index]->Transforms[TransformIndex].b[1];
DeltaX = Fractals[Index]->DeltaX;
DeltaY = Fractals[Index]->DeltaY;
Scale = Fractals[Index]->Scale;
xp = A0 * x + A1 * y + B0;
yp = A2 * x + A3 * y + B1;
x = DeltaX + Scale * (xp * WINDOW_WIDTH);
y = DeltaY - Scale * (yp * aspect * WINDOW_HEIGHT);
SDL_WriteSurfacePixel(surface, x, y, color.r, color.g, color.b, color.a);
x = xp;
y = yp;
}