MallaBarrido::MallaBarrido(const char * nombre_arch ,float x,float y,float z, unsigned ntraslaciones){ std::vector<float> vertices_ply ; // coordenadas de vértices ply::read_vertices( nombre_arch, vertices_ply); int tam = vertices_ply.size(); int n=tam/3; for (int j=0;j<=ntraslaciones;j++){ for (int i=0;i<tam;i=i+3){ stlVertices.push_back(Tupla3f(vertices_ply[i]+x*j/ntraslaciones, vertices_ply[i+1]+y*j/ntraslaciones,vertices_ply[i+2]+z*j/ntraslaciones)); } } for(int j=0;j<ntraslaciones;j++){ for(int i=0;i<n-1;i++){ // cada iteracion une dos perfiles consecutivos stlCaras.push_back(Tupla3i(i+n*j,i+1+n*j,i+n*(j+1))); stlCaras.push_back(Tupla3i(i+n*(j+1),i+1+n*(j+1),i+1+n*j)); } //cierre del tubo creado stlCaras.push_back(Tupla3i(j*n+n-1,j*n,j*n+n)); stlCaras.push_back(Tupla3i(j*n+n,n-1+n*(j+1),j*n+n-1)); } }
Cilindro::Cilindro(int num_caras){ nombre_obj = "Cilindro"; //VÉRTICES //Vamos añadiendo tuplas con las coordenadas de los vértices de la base inferior for (int i=0; i < num_caras; i++){ vertices.push_back(Tupla3f(cos((2*PI/(num_caras-1))*i),0,sin((2*PI/(num_caras-1))*i))); } //Vamos añadiendo tuplas con las coordenadas de los vértices de la base superior for (int i=0; i < num_caras; i++){ vertices.push_back(Tupla3f(cos((2*PI/(num_caras-1))*i),1,sin((2*PI/(num_caras-1))*i))); } //Añado el vértice del centro de la base superior ~ luego lo llamaremos como vertices.size()-2 vertices.push_back(Tupla3f(0,1,0)); //Añado el vértice del centro de la base inferior ~ luego lo llamaremos como vertices.size()-1 vertices.push_back(Tupla3f(0,0,0)); //CARAS //caras de la base inferior //recorremos la primera mitad de los vértices,creando triángulos con el centro inferior for (int i=0; i < ((vertices.size()/2)-1); i++){ caras.push_back(Tupla3i(i, (i+1)%((vertices.size()/2)-1), vertices.size()-1)); } //caras de la base superior //recorremos la segunda mitad de los vértices, creando triángulos con el centro superior for (int i=((vertices.size()/2)-1); i < (vertices.size()-2); i++){ caras.push_back(Tupla3i(i, (i+1)%(vertices.size()-2), vertices.size()-2)); } //caras laterales for (int i=0; i < ((vertices.size()/2)-1); i++){ caras.push_back(Tupla3i(i, (i+1)%((vertices.size()/2)-1), i+((vertices.size()/2)-1))); //creación de triángulos desde la base inferior a la superior caras.push_back(Tupla3i(i + ((vertices.size()/2)-1), ((i+1)%((vertices.size()/2)-1)) + ((vertices.size()/2)-1), (i+1)%((vertices.size()/2)-1))); } }
Cilindro::Cilindro(){ nombre_obj = "Cilindro"; num_caras = 50; // DEBE SER MÍNIMO 5 num_vertices = (num_caras-2)*2; angulo = (2*PI)/(num_vertices/2); rad = angulo; tablaVertices.push_back(Tupla3f(0,-1,1)); tablaVertices.push_back(Tupla3f(0,1,1)); for (int i=1; i<num_vertices/2; i++){ tablaVertices.push_back(Tupla3f(sin(rad),-1,cos(rad))); tablaVertices.push_back(Tupla3f(sin(rad),1,cos(rad))); rad = rad+angulo; } tablaVertices.push_back(Tupla3f(0,-1,0)); //centro de la base inferior del cilindro tablaVertices.push_back(Tupla3f(0,1,0)); //centro de la base superior del cilindro for (int i=0; i<num_vertices-2; i++){ tablaCaras.push_back(Tupla3i(i,i+1,i+2)); } tablaCaras.push_back(Tupla3i(num_vertices-2,num_vertices-1,0)); tablaCaras.push_back(Tupla3i(num_vertices-1,0,1)); for (int i=0; i<num_vertices-2; i++){ if (i%2==0){ tablaCaras.push_back(Tupla3i(i,num_vertices,i+2)); } else{ tablaCaras.push_back(Tupla3i(i,num_vertices+1,i+2)); } } if (num_vertices%2==0){ tablaCaras.push_back(Tupla3i(num_vertices-2,num_vertices,0)); tablaCaras.push_back(Tupla3i(num_vertices-1,num_vertices+1,1)); } else if (num_vertices%2!=0){ tablaCaras.push_back(Tupla3i(num_vertices-2,num_vertices+1,1)); tablaCaras.push_back(Tupla3i(num_vertices-1,num_vertices,0)); } }
Toro::Toro(){ nombre_obj="Toro"; int n=100; // numero de puntos por circunferencia int m=100; //numero de anillos for (int i=0;i<m;i++){ //Numero de circunferencias for(int j=0;j<n;j++){ //Numero de puntos por circu stlVertices.push_back(Tupla3f(cos(2*i*M_PI/m)*(2.5+cos(2*j*M_PI/n)), sin(2*i*M_PI/m)*(2.5+cos(2*j*M_PI/n)),sin(2*j*M_PI/n))); } } // Insercion de indices de caras for(int j=0;j<m-1;j++){ // Cada iteracion es un anillo for (int i=0;i<n-1;i++){ stlCaras.push_back(Tupla3i(i+j*n,i+1+j*n,n+i+j*n)); //media dentadura inferior sin cerrar } stlCaras.push_back(Tupla3i(n-1+j*n,0+j*n,2*n-1+j*n)); // cierre dentadura inferior for (int i=0;i<n-1;i++){ stlCaras.push_back(Tupla3i(n+i+j*n,n+i+1+j*n,i+1+j*n)); //media dentadura superior sin cerrar } stlCaras.push_back(Tupla3i(2*n-1+j*n,n+j*n,0+j*n)); // cierre dentadura inferior } // ULTIMO ANILLO for(int i=0;i<n-1;i++){ stlCaras.push_back(Tupla3i((m-1)*n+i,i+1,(m-1)*n+i+1)); //dentadura inferior sin cerrar } stlCaras.push_back(Tupla3i(0,n-1,stlVertices.size()-1)); //cierre dentadura inferior for(int i=0;i<n-1;i++){ stlCaras.push_back(Tupla3i(i,i+1,(m-1)*n+i)); // dentadura superior sin cerrar } stlCaras.push_back(Tupla3i(stlVertices.size()-1,0,2)); // cierre dentadura superior }
Cubo::Cubo(){ nombre_obj = "Cubo"; tablaVertices.push_back(Tupla3f(-0.5,-0.5,0.5)); tablaVertices.push_back(Tupla3f(-0.5,-0.5,-0.5)); tablaVertices.push_back(Tupla3f(0.5,-0.5,-0.5)); tablaVertices.push_back(Tupla3f(0.5,-0.5,0.5)); tablaVertices.push_back(Tupla3f(-0.5,0.5,0.5)); tablaVertices.push_back(Tupla3f(-0.5,0.5,-0.5)); tablaVertices.push_back(Tupla3f(0.5,0.5,-0.5)); tablaVertices.push_back(Tupla3f(0.5,0.5,0.5)); tablaCaras.push_back(Tupla3i(0,1,2)); tablaCaras.push_back(Tupla3i(0,3,2)); tablaCaras.push_back(Tupla3i(2,6,7)); tablaCaras.push_back(Tupla3i(7,3,2)); tablaCaras.push_back(Tupla3i(4,5,6)); tablaCaras.push_back(Tupla3i(4,6,7)); tablaCaras.push_back(Tupla3i(0,5,1)); tablaCaras.push_back(Tupla3i(5,0,4)); tablaCaras.push_back(Tupla3i(0,7,3)); tablaCaras.push_back(Tupla3i(0,7,4)); tablaCaras.push_back(Tupla3i(1,6,2)); tablaCaras.push_back(Tupla3i(6,1,5)); }
MallaRevol::MallaRevol( const char * nombre_arch, unsigned nperfiles, bool quiero_coord_textura ){ std::vector<float> vertices_ply; // coordenadas de vértices ply::read_vertices( nombre_arch, vertices_ply ); //Creamos los vértices /* * [cos ángulo, 0, sin ángulo] * R(y) = [0, 1, 0] * [-sin ángulo, 0, cos ángulo] */ for (int i=0; i < vertices_ply.size(); i+=3){ //i+=3 es porque en vertices_ply están de 3 en 3 (para leer la x de cada vértice) luego leemos la y con +1 y la z con +2 for (int j=0; j < nperfiles; j++){ //para girar nperfiles veces vertices.push_back(Tupla3f(cos (((2*PI)/nperfiles)*j)*vertices_ply[i] + sin (((2*PI)/nperfiles)*j)*vertices_ply[i+2], vertices_ply[i+1], - sin (((2*PI)/nperfiles)*j)*vertices_ply[i] + cos (((2*PI)/nperfiles)*j) * vertices_ply[i+2])); } } //Creamos las caras laterales //Mejor en redondo porque la estructura la he creado en redondo for (int i=0; i < (vertices.size() - nperfiles) ; i+=nperfiles){ for (int j=0; j < nperfiles ; j++){ int vertice_superior = i + j + nperfiles; int vertice_adyacente = i + j + 1; int vertice_diagonal = i + j + 1 + nperfiles; if (j == nperfiles-1){ //máximo al que el j puede llegar (este if actúa como un módulo) vertice_adyacente = i; // el vértice de al lado tiene que ser el primero para que el último se una con el de al lado (que es el primero) vertice_diagonal = vertice_adyacente + nperfiles; } caras.push_back(Tupla3i(i+j, vertice_adyacente, vertice_diagonal)); caras.push_back(Tupla3i(i+j, vertice_diagonal, vertice_superior)); } } //En el punto máximo y en el punto mínimo (primero y último) las x y las z son 0. Tupla3f vertice_inicial = vertices[0]; Tupla3f vertice_final = vertices[vertices.size()-1]; vertices.push_back(Tupla3f(0,vertice_inicial[1],0)); //vertices.size()-2 es el punto medio de la base inferior vertices.push_back(Tupla3f(0,vertice_final[1],0)); //vertices.size()-1 es el punto medio de la base superior for (int i=0; i < nperfiles; i++){ caras.push_back(Tupla3i(i, (i+1)%nperfiles, vertices.size()-2)); //creación de la tapa de la base inferior } for (int i = 0; i < nperfiles ; i++){ caras.push_back(Tupla3i(i+(vertices.size()-3-nperfiles), ((i+1)%nperfiles)+(vertices.size()-3-nperfiles), vertices.size()-1)); //creación de la tapa de la base superior } // Añado las coordenadas de textura if (quiero_coord_textura == true){ std::vector<float> s(nperfiles); std::vector<float> d(vertices.size()); //distancia (medida a lo largo del perfil) entre el primer vértice del mismo (v0) y dicho vértice j-ésimo. std::vector<float> t(vertices.size()); for (int i = 0; i < nperfiles; i++){ for (int j = 0; j < vertices.size(); j++){ /* El perfil de partida tiene vertices.size() vértices * Hay nperfiles copias del perfil * y en cada copia hay vertices.size() vértices * * El j-ésimo vértice en la i-ésima copia del perfil es qij * y tendrá unas coordenadas de textura (si, tj) donde si es común a todos los vértices en una copia del perfil. */ s[i] = (float)i / (nperfiles - 1); //coordenada X en el espacio de la textura. Va desde 0 en el 1º perfil hasta 1 en el último de ellos. d[0] = 0; Tupla3f resta = vertices[j+1] - vertices[j]; float resta_normalizada = sqrt(resta.dot(resta)); d[j+1] = d[j] + resta_normalizada; t[j] = d[j]/d[vertices.size()-1]; //coordenada Y en el espacio de la textura. coordenadas_textura.push_back(Tupla2f(s[i],t[j])); } } } }