A Curva de Koch (Fractal Floco de Neve)
Dando continuidade aos artigos sobre fractais, o desenho abaixo mostra um fractal conhecido como a Curva de Koch, ou fractal do Floco de Neve, que foi pesquisado inicialmente pelo matemático sueco Helge von Koch em 1904, e recebeu este nome por sua semelhança com um floco de neve.
O fractal do floco de neve é uma excelente figura para entendermos os conceitos de fractais, pois o mesmo apresenta as características de fractais que vimos:
-
Ao navegarmos na escala do fractal, e se tomarmos uma parte da figura ela parecer-se-á com qualquer outra parte do fractal;
-
A cada iteração o perímetro do fractal aumenta, e, após n iterações, o mesmo tende ao infinito.
O Fractal do Floco de Neve
O fractal do Floco de Neve, consiste em um triângulo equilátero inicial, de onde tomamos cada um de seus lados e o dividimos em três segmentos de reta iguais. Retiramos, então, o segmento do meio e o substituímos por outro triângulo equilátero sem a base. Demonstramos abaixo as iterações de um dos lados do triângulo inicial.
Iterações:
0)
1)
2)
3)
4)
5)
Cálculo dos pontos
Situação inicial:
a_______________________b
Após a primeira iteração.
Onde calculamos cada ponto da seguinte maneira:
O programa fonte
Para a programação do fractal, utilizamos a linguagem C. Também utilizamos a alocação dinâmica de memória para evitar o desperdício da mesma ao utilizarmos vetores e matrizes de tamanhos fixos.
#define MAX_ITERACOES 6
#define WIDTH 400
#define HEIGHT 250
struct ponto {
double x,y;
} a,b,r,m,s,t;
struct segmento {
double x1,y1,x2,y2;
struct segmento *prox;
}*p_ini,*p_ini_aux,*p_new,*p_act,*p_act_aux,*p_aux;
double fator;
struct segmento *aloca( void ) {
struct segmento *ptr;
if((ptr=(struct segmento *) malloc(sizeof(struct segmento))) == NULL) {
printf("Erro 4: Nao consigo alocar memoria suficiente p/ a lista.\n");
exit(1);
}
return ptr;
}
struct segmento *atribui(struct segmento *p_aux,double x1,double y1,double x2,double y2,struct segmento *p_prox){
p_aux->x1=x1;
p_aux->y1=y1;
p_aux->x2=x2;
p_aux->y2=y2;
p_aux->prox=p_prox;
return p_aux;
}
void limpa(struct segmento *p_ini) {
struct segmento *p_act, *p_aux;
p_act = p_ini;
while( p_aux->prox != NULL ) {
p_aux = p_act;
p_act = p_act->prox;
free(p_aux);
}
}
void tela_inicial(double x_ini,double x_fim,double y_ini,double y_fim,double x_aux,double y_aux) {
setfillstyle(1,16);
bar((x_ini-x_ini)/x_aux,
(y_ini-y_ini)/y_aux,
(x_fim-x_ini)/x_aux,
(y_fim-y_ini)/y_aux);
setcolor(1);
}
void main() {
double deltax,deltay;
double x_ini,x_fim,y_ini,y_fim,x_aux,y_aux;
int i;
/* ABRINDO O MODO GRAFICO */
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "");
errorcode = graphresult();
if (errorcode != grOk) {
printf("Erro 02: Impossivel abrir o modo grafico.\n");
exit(1);
}
// LIMITES DO GRAFICO
x_ini = 0;
x_fim = 6;
y_ini = 0;
y_fim = 6;
// VARIAVEIS AUXILIARES PARA ECONOMIZAR TEMPO
x_aux = (x_fim - x_ini) / WIDTH;
y_aux = (y_fim - y_ini) / HEIGHT;
//GRAFICO
tela_inicial(x_ini,x_fim,y_ini,y_fim,x_aux,y_aux);
/* Inicio koch */
fator = sqrt(3) / 6;
p_act = p_ini = atribui(aloca(),1,3,5,3,NULL);
i=0;
while(i<MAX_ITERACOES) {
/* Lista auxiliar */
p_ini_aux = NULL;
/* desenho do fractal */
p_act=p_ini;
while(p_act != NULL) {
if((((p_act->x1 - x_ini) != 0) &&
((p_act->y1 - y_ini) != 0) &&
((p_act->x2 - x_ini) != 0) &&
((p_act->y2 - y_ini) != 0))) {
line((p_act->x1-x_ini)/x_aux,(p_act->y1-y_ini)/y_aux,(p_act->x2-x_ini)/x_aux,(p_act->y2-y_ini)/y_aux);
}
p_act = p_act->prox;
}
getch();
tela_inicial(x_ini,x_fim,y_ini,y_fim,x_aux,y_aux);
p_act = p_ini;
/* fim desenho do fractal */
while( p_act != NULL ) {
a.x=p_act->x1;
a.y=p_act->y1;
b.x=p_act->x2;
b.y=p_act->y2;
r.x = ( 2.0 * a.x + b.x ) / 3.0;
r.y = ( 2.0 * a.y + b.y ) / 3.0;
t.x = ( a.x + 2.0 * b.x ) / 3.0;
t.y = ( a.y + 2.0 * b.y ) / 3.0;
m.x = ( a.x + b.x ) / 2.0;
m.y = ( a.y + b.y ) / 2.0;
deltax = b.x - a.x;
deltay = b.y - a.y;
s.x = m.x + (fator * deltay);
s.y = m.y - (fator * deltax);
p_new=atribui(aloca(),a.x,a.y,r.x,r.y,NULL);
if(p_ini_aux == NULL)
p_ini_aux = p_new;
else
p_act_aux->prox = p_new;
p_act_aux = p_new;
p_new=atribui(aloca(),r.x,r.y,s.x,s.y,NULL);
p_act_aux->prox = p_new;
p_act_aux = p_new;
p_new=atribui(aloca(),s.x,s.y,t.x,t.y,NULL);
p_act_aux->prox = p_new;
p_act_aux = p_new;
p_new=atribui(aloca(),t.x,t.y,b.x,b.y,NULL);
p_act_aux->prox = p_new;
p_act_aux = p_new;
p_aux = p_act;
p_act = p_act->prox;
free(p_aux);
p_ini = p_act;
}
/* transferindo lista auxiliar p/ lista original */
p_act_aux = p_ini_aux;
p_ini = NULL;
while(p_act_aux != NULL) {
p_new = aloca();
if (p_ini == NULL)
p_ini = p_new;
else
p_act->prox = p_new;
p_act = p_new;
atribui(p_act,p_act_aux->x1,p_act_aux->y1,p_act_aux->x2,p_act_aux->y2,NULL);
p_aux = p_act_aux;
p_act_aux = p_act_aux->prox;
p_ini_aux = p_act_aux;
free(p_aux);
}
p_act = p_ini;
i++;
} /* fim kock */
limpa(p_ini); // limpando lista original
closegraph();
}
Referências
AGUIAR, C. E. A curva de Koch. Disponível em: <http://cis.elizabethtowncc.com/Rene/VonKochSnowflakeHome.html>. Acesso em: abr. 2002.
GLYNN, E. F. Von Koch curve. Disponível em: <http://www.efg2.com/Lab/FractalsAndChaos/vonKochCurve.htm>. Acesso em: abr. 2002.
GUARNEROS-MATA, R. Von Koch's snowflake fractal curve. Disponível em:
<http://cis.elizabethtowncc.com/Rene/VonKochSnowflakeHome.html>. Acesso em: abr. 2002.