Миры нерегулярной геометрии                          
14.1.95                                                                       
                                      
    В свое время получение            
 правдоподобного пейзажа с помощью    
 компьютера было чрезвычайно трудным  
 делом. Художник мог провести за      
 клавиатурой многие часы, комбинируя  
 отрезки, дуги, конусы и пирамиды, но 
 так и не получить ничего похожего на 
 реальность. Однако начиная с 1975    
 года благодаря работам французского  
 математика Бенуа Мандельброта эта    
 задача существенно упростилась. Более
 чем двадцатилетние исследования этого
 ученого привели к появлению методов, 
 которые позволяют компьютерам        
 рисовать ландшафты и другие          
"естественные" картины, а также совершенно фантастические формы, не имеющие   
никакого сходства с тем, что встречается на Земле.                            
   Свою теорию Мандельброт назвал фрактальной геометрией (от лат. fractio -   
часть, дробь), подчеркивая тем самым дробную размерность некоторых            
геометрических преобразований. Например, прямая - одномерна, плоскость -      
двумерна, о кривой же, проходящей почти через все точки плоскости, можно      
сказать, что ее размерность больше единицы, но меньше двух. По словам         
Мандельброта, фрактали "позволяют охватить причуды природы - изломы дубовой   
коры, растрескавшийся ил в руслах пересохших рек, листья капусты брокколи. Все
это нерегулярные формы, обладающие вместе с тем достаточной регулярностью,    
чтобы их можно было описать математически".                                   
   Простейшие процедуры создания фракталей сводятся к правилам воспроизведения
исходных форм, которые могут повторяться сотни и тысячи раз во все            
возрастающем масштабе. Определенная степень случайности, введенная в формулы, 
делает результаты отчасти непредсказуемыми и позволяет получать как           
правдоподобные пейзажи, так и причудливые геометрические преобразования.      
                                                                              
Компьютер обретает разум, М.Мир 1990                                          
                                                                              
   На рисунке вверху, каждая сторона треугольника преобразуется по правилу:   
____ -> _/\_, каждый полученный отрезок затем преобразуется аналогично и т.д. 
Использовано 900000 итераций. Использовалась программа, аналогичная следующей:
                                                                              
#include <graphics.h>                                                         
#include <bios.h>                                                             
#include <stdlib.h>                                                           
#include <math.h>                                                             
                                                                              
#define N_O     (6000)                                                        
#define RAD     (3.1415926)                                                   
#define TUTU    (4)                                                           
                                                                              
struct line {                                                                 
        int x1, y1, x2, y2;                                                   
} Otr[N_O];                                                                   
                                                                              
unsigned p = 0;                                                               
                                                                              
it(unsigned u) {                                                              
        double a;                                                             
        int xa, xb, xc, ya, yb, yc, t,s, r;                                   
        struct line o;                                                        
                                                                              
        r = sqrt(pow(Otr[u].y2 - Otr[u].y1, 2) +                              
                        pow(Otr[u].x2 - Otr[u].x1, 2));                       
        if ( r < TUTU ) {                                                     
                return 1;                                                     
        }                                                                     
        o = Otr[u];                                                           
                                                                              
        a = abs(Otr[u].y2 - Otr[u].y1);                                       
        if (abs(Otr[u].x2 - Otr[u].x1) < 0.01)                                
                a = RAD/2;                                                    
        else a = atan( a / abs(Otr[u].x2 - Otr[u].x1) );                      
                                                                              
        if (Otr[u].y2 >= Otr[u].y1) {                                         
                if (Otr[u].x2 < Otr[u].x1) a = RAD - a;                       
        } else {                                                              
                if (Otr[u].x2 >= Otr[u].x1) a = - a;                          
                else a = a - RAD;                                             
        }                                                                     
                                                                              
        t = Otr[u].x1;  s = Otr[u].y1;                                        
        Otr[u].x1 = t * cos(-a) - s * sin(-a);                                
        Otr[u].y1 = t * sin(-a) + s * cos(-a);                                
        t = Otr[u].x2;  s = Otr[u].y2;                                        
        Otr[u].x2 = t * cos(-a) - s * sin(-a);                                
        Otr[u].y2 = t * sin(-a) + s * cos(-a);                                
                                                                              
        xa = 0.3333 * r + Otr[u].x1;                                          
        xb = 0.6666 * r + Otr[u].x1;                                          
        xc = 0.5555 * r + Otr[u].x1;                                          
                                                                              
        ya = yb = Otr[u].y1;                                                  
        if (random(1000) < 500)                                               
                yc = ya + 0.5/sqrt(3.0)*r;                                    
        else    yc = ya - 0.5/sqrt(3.0)*r;                                    
                                                                              
        t = xa; s = ya;                                                       
        xa = t * cos(a) - s * sin(a);                                         
        ya = t * sin(a) + s * cos(a);                                         
                                                                              
        t = xb; s = yb;                                                       
        xb = t * cos(a) - s * sin(a);                                         
        yb = t * sin(a) + s * cos(a);                                         
                                                                              
        t = xc; s = yc;                                                       
        xc = t * cos(a) - s * sin(a);                                         
        yc = t * sin(a) + s * cos(a);                                         
                                                                              
        Otr[p].x2 = o.x2;                                                     
        Otr[p].y2 = o.y2;                                                     
                                                                              
        Otr[u].x1 = o.x1;                                                     
        Otr[u].y1 = o.y1;                                                     
                                                                              
        Otr[u].x2 = Otr[p+1].x1 = xa;                                         
        Otr[u].y2 = Otr[p+1].y1 = ya;                                         
                                                                              
        Otr[p+1].x2 = Otr[p+2].x1 = xc;                                       
        Otr[p+1].y2 = Otr[p+2].y1 = yc;                                       
                                                                              
        Otr[p+2].x2 = Otr[p].x1 = xb;                                         
        Otr[p+2].y2 = Otr[p].y1 = yb;                                         
                                                                              
        p = p + 3;                                                            
                                                                              
        if(abs(xa - xc) < TUTU) {                                             
                return 1;                                                     
        }                                                                     
        return 0;                                                             
}                                                                             
                                                                              
main() {                                                                      
        int i,j, c, dr = EGA, md = EGAHI;                                     
        unsigned k = 0;                                                       
                                                                              
        initgraph(&dr, &md, "");                                              
                                                                              
        Otr[0].x1 = 10; Otr[0].y1 = 200;                                      
        Otr[0].x2 = 400; Otr[0].y2 = 200;                                     
        Otr[1].x1 = 400; Otr[1].y1 = 200;                                     
        Otr[1].x2 = 200; Otr[1].y2 = 50;                                      
        Otr[2].x1 = 200; Otr[2].y1 = 50;                                      
        Otr[2].x2 = 10; Otr[2].y2 = 200;                                      
        p = 3;                                                                
        randomize();                                                          
        setfillstyle(EMPTY_FILL,0);                                           
                                                                              
        while (p < N_O && k <= p) {                                           
                i = p;                                                        
                k = 0;                                                        
                while ( k < i && p < N_O) {                                   
                        it(k);                                                
                        k++;                                                  
                }                                                             
                if (i == p) {                                                 
                        break;                                                
                }                                                             
                bar(0,0, 640,350);                                            
                for (i = 0; i < p; i++)                                       
                        line(Otr[i].x1, Otr[i].y1, Otr[i].x2, Otr[i].y2);     
                if (bioskey(1)) break;                                        
        }                                                                     
        bioskey(0);                                                           
        restorecrtmode();                                                     
        return 0;                                                             
}                                                                             
                                                                              


HyperText/CGI-HTML, v. 3.6.4 (C)1994-2000 M.Zakharov