Фракталы - это просто
![топ 100 блогов](/media/images/default.jpg)
![Фракталы - это просто](https://upload.wikimedia.org/wikipedia/commons/thumb/2/21/Mandel_zoom_00_mandelbrot_set.jpg/250px-Mandel_zoom_00_mandelbrot_set.jpg)
Давайте запрограммируем фрактал так, чтобы его можно было удобно рассматривать: приближать, отдалять и перемещать. Плюс можно добавить немного анимации. В итоге получим такуие картинки:
![Фракталы - это просто](http://image.auditory.ru/images/3286f1.png)
![Фракталы - это просто](http://share.auditory.ru/2010/Vasily.Matveev/link_photo/f2.png)
Как же это сделать? Конечно, запрограммировать!
Для множеста Мандельброта доказано, что если для точки
![Фракталы - это просто](https://upload.wikimedia.org/math/7/b/6/7b657facf3f0f6938e8d3bb7aacc01ba.png)
Подробности - в коде:
Copy Source | Copy HTML
//Include SDL functions and datatypes
#include "SDL/SDL.h"
void
put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel )
{
//Convert the pixels to 32 bit
Uint32 *pixels = (Uint32 *)surface->pixels;
//Set the pixel
pixels[ ( y * surface->w ) + x ]
= pixel;
}
void
draw_fractal(SDL_Surface *screen, float x_min, float x_max, float y_min, float y_max)
{
int img_w = screen->w;
int img_h = screen->h;
double step =
(x_max - x_min)/double(img_w);
int x= 0, y= 0;
unsigned color;
static unsigned add_color = 1;
add_color++;
y = 0;
for (double yy=y_min; yy
x = 0;
for
(double xx=x_min; xx
double ix= 0,
iy= 0;
double X = xx, Y =
yy;
int n =
0;
while
( (ix*ix + iy*iy < 5) && (n<64))
{
ix =
X*X - Y*Y + xx;
iy =
2*X*Y + yy;
X =
ix;
Y =
iy;
n++;
}
if (x
< img_h-1) {
put_pixel32(screen, x, y, n*5*add_color);
}
x++;
}
if (y>=img_h) break;
y++;
}
}
int main( int argc, char* args[] )
{
SDL_Surface* screen = NULL;
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Set up screen
int img_w = 1024;
int img_h = 768;
screen =
SDL_SetVideoMode( img_w, img_h, 32, SDL_DOUBLEBUF );
float x_max = 1;
float x_min = -2;
float y_max = ((x_max-x_min)/2.)*img_h/img_w;
float y_min = -1*y_max;
SDL_Event event;
bool close = false;
while (!close) {
//handling events
while ( SDL_PollEvent(&event) )
{
if( event.type == SDL_QUIT )
close = true;
//moving fractal
if
( event.type == SDL_KEYDOWN) {
switch(event.key.keysym.sym){
case
SDLK_LEFT:
x_min
+= (x_max-x_min)/8;
x_max
+= (x_max-x_min)/8;
break;
case
SDLK_RIGHT:
x_min
-= (x_max-x_min)/8;
x_max
-= (x_max-x_min)/8;
break;
case
SDLK_DOWN:
y_min
-= (y_max-y_min)/8;
y_max
-= (y_max-y_min)/8;
break;
case
SDLK_UP:
y_min
+= (y_max-y_min)/8;
y_max
+= (y_max-y_min)/8;
break;
case
SDLK_z:
x_min
+= (x_max-x_min)/8;
x_max
-= (x_max-x_min)/8;
y_max
-= (y_max-y_min)/8;
y_min
+= (y_max-y_min)/8;
break;
case
SDLK_x:
x_min
-= (x_max-x_min)/8;
x_max
+= (x_max-x_min)/8;
y_max
+= (y_max-y_min)/8;
y_min
-= (y_max-y_min)/8;
break;
}
}
}
draw_fractal(screen, x_min, x_max, y_min, y_max);
//update screen
SDL_Flip( screen );
SDL_Delay(100);
}
//Free the loaded image
SDL_FreeSurface( screen );
//Quit SDL
SDL_Quit();
return 0;
}
Компилируем строкой
g++ <�имя файла с кодом> -lSDL -o fractal.bin
и запускаем! В системе должен стоять SDL - я отрисовываю через него. Фрактал можно двигать стрелками, приближать (это же фрактал, при приближении детализированность увеличивается, пока хватитает мощности компа) - Z, отдалять - X.
Have fun!
|
</> |