Unlimited Faxes, No Fees, Dedicated Phone Number
Triangulo de Sierpinski
Explicación del método
Partimos de un triangulo inicial
GLfloat x;
GLfloat y;
GLfloat z; //La coordenada z no se usa por que estamos en
2D
} punto;
typedef struct{ //Para un triangulo
punto v[3];
}face;
vector<face> Triangulos; //Vector de triangulos
face primera; //Primer triangulo
//Damos las coordenadas de los 3 puntos en sentido
contrario a las agujas del reloj
primera.v[0].x=0.0f;
primera.v[0].y=lado*sqrt(3.0f/4.0f);
primera.v[0].z=0.0f;
primera.v[1].x=-lado/2;
primera.v[1].y=0.0f;
primera.v[1].z=0.0f;
primera.v[2].x=lado/2;
primera.v[2].y=0.0f;
primera.v[2].z=0.0f;
Triangulos.push_back(primera);
}
void pintar1(face f){
glBegin(GL_TRIANGLES);
glVertex3f(f.v[0].x,f.v[0].y,f.v[0].z);
glVertex3f(f.v[1].x,f.v[1].y,f.v[1].z);
glVertex3f(f.v[2].x,f.v[2].y,f.v[2].z);
glEnd();
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth( 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Se activa la matriz del modelador
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Centramos el triangulo
glTranslatef(0.0f,-(lado*sqrt(3.0f/4.0f))/3,-10.0f);
glColor3f(1.0f,0.0f,0.0f); //Color rojo
//Pintamos cada triangulo del vector
for(int i=0; i<Triangulos.size();i++)
pintar1(Triangulos[i]);
glutSwapBuffers();
glFlush();
}
glutInit(&argc, argv);
glutInitWindowPosition(50,50);
glutInitWindowSize (W_WIDTH, W_HEIGHT);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Ventana con el Visual C++ y
glut");
//Funcion de dibujo
glutDisplayFunc(Display);
//Manejador de teclado
glutKeyboardFunc(tecla);
//Configuración de la matriz de proyeccion
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0f,5.0f,-5.0f,5.0f,-150.0,150.0f);
init(); //Creamos el primer triangulo
//Lazo principal
glutMainLoop();
return 0;
}
switch (c) {
case '+': //Hacer la
siguiente iteración
hacerMas();
printf("Numero de triangulos: %d\n",Triangulos.size());
break;
case '*': //Volver al
triangulo inicial aumentando su tamaño
lado+=1.0;
Triangulos.clear();
init();
break;
case
27: // Se ha pulsado Esc.
exit(0); // Salimos del programa
break;
default:
break;
}
glutPostRedisplay();
}
Método para llevar a cabo la siguiente iteración:
Este es el método mas interesante
de todo este código.
Lo que hacemos es recorrer el
vector de los triángulos existentes, y para cada uno de ellos, buscar los puntos medios
de sus lados, y definir los 3 triángulos que lo sustituirán.
Los nuevos triángulos los
guardamos en un vector a parte para no recorrerlos en la misma iteración en la que han
sido creados. Finalmente devolvemos el vector con los nuevos triángulos.
vector<face> aux; //Vector que devolveremos
for(int j=0;j<Triangulos.size();j++){
face
leido=Triangulos[j];
face
nueva1,nueva2,nueva3; //Los 3 nuevos triangulos
nueva1.v[0].x=leido.v[0].x;
nueva1.v[0].y=leido.v[0].y;
nueva1.v[0].z=0.0f;
nueva1.v[1].x=(leido.v[0].x+leido.v[1].x)/2.0f;
nueva1.v[1].y=(leido.v[0].y+leido.v[1].y)/2.0f;
nueva1.v[1].z=0.0f;
nueva1.v[2].x=(leido.v[0].x+leido.v[2].x)/2.0f;
nueva1.v[2].y=(leido.v[0].y+leido.v[2].y)/2.0f;
nueva1.v[2].z=0.0f;
aux.push_back(nueva1);//Lo añadimos al vector
nueva2.v[0].x=leido.v[1].x;
nueva2.v[0].y=leido.v[1].y;
nueva2.v[0].z=0.0f;
nueva2.v[1].x=(leido.v[2].x+leido.v[1].x)/2.0f;
nueva2.v[1].y=(leido.v[2].y+leido.v[1].y)/2.0f;
nueva2.v[1].z=0.0f;
nueva2.v[2].x=(leido.v[0].x+leido.v[1].x)/2.0f;
nueva2.v[2].y=(leido.v[0].y+leido.v[1].y)/2.0f;
nueva2.v[2].z=0.0f;
aux.push_back(nueva2);
//Lo añadimos al vector
nueva3.v[0].x=leido.v[2].x;
nueva3.v[0].y=leido.v[2].y;
nueva3.v[0].z=0.0f;
nueva3.v[1].x=(leido.v[0].x+leido.v[2].x)/2.0f;
nueva3.v[1].y=(leido.v[0].y+leido.v[2].y)/2.0f;
nueva3.v[1].z=0.0f;
nueva3.v[2].x=(leido.v[1].x+leido.v[2].x)/2.0f;
nueva3.v[2].y=(leido.v[1].y+leido.v[2].y)/2.0f;
nueva3.v[2].z=0.0f;
aux.push_back(nueva3);
//Lo añadimos al vector
}
Triangulos.clear();//Eliminamos los antiguos
Triangulos=aux;//Ponemos los nuevos
aux.clear();
}
Dejá un comentario, sugerencia u opinión