void SCANLINE::Compute_Poly_Normal() { vector< vector<float> > temp_vertex_normal(world_vertex.size(),vector<float>(3)); vector <float> temp_I_light(3);//light intensity I_light = temp_I_light; I_light[0] = 1.0;//R I_light[1] = 0.64;//G I_light[2] = 0;//B vector <float> poly_vector_1(3); vector <float> poly_vector_2(3); vector <float> poly_normal(3); vector <float> temp_H(3); //calculus H vector_summation(temp_H, vec_light,vec_view); for (int j=0; j<3 ;j++ ) H_specular.push_back(temp_H[j]/vector_length(temp_H)); ///---Intensity ambient----Ka*I for (int j=0; j<3 ;j++ ) Intensity_ambient.push_back(K_ambient*I_light[j]); for(int i=0; i<(int)Poly.size(); i++) {//compute polygon normal vector_subtraction(poly_vector_1, world_vertex[Poly[i][2]-1], world_vertex[Poly[i][1]-1]); vector_subtraction(poly_vector_2, world_vertex[Poly[i][2]-1], world_vertex[Poly[i][3]-1]); //compute 2 vector on one polygon cross_product3D(poly_normal, poly_vector_1, poly_vector_2); //calculus cross product for(int j=1; j<(int)Poly[i][0]+1 ;j++) {//add normal of neibor polygon to vertex for (int p=0; p<3 ;p++ ) temp_vertex_normal[Poly[i][j]-1][p] += poly_normal[p]; } } for(int i=0; i<(int)temp_vertex_normal.size() ;i++ ) { float temp_length = vector_length(temp_vertex_normal[i]); for (int j=0; j<3 ;j++ ) { //normalize the normal on vertex temp_vertex_normal[i][j] = temp_vertex_normal[i][j] / temp_length; } } vertex_normal = temp_vertex_normal; //vertex normals as average of surrounding neibor polygon's normal }
/* change m into an orthogonal matrix */ Matrix *gram_schmidt(Matrix *m){ Matrix *ortho; double *ortho_vector, *temp; unsigned int i, j; if(m != NULL || m->rows == m->columns || zero_vector(m) != 1){ /* create my empy matrix to have new orthogonal vector be added to */ ortho = constructor(m->rows, 1); /* initialize with the first vector */ free(ortho->numbers[0]); ortho_vector = malloc(sizeof(double)*m->rows); for(i = 0; i < m->rows; i++) ortho_vector[i] = m->numbers[0][i]; ortho->numbers[0] = ortho_vector; /* now loop and go through the gs system */ for(i = 1; i < m->columns; i++){ /* first initialize to the regular vector */ ortho_vector = malloc(sizeof(double)*m->rows); for(j = 0; j < m->rows; j++) ortho_vector[j] = m->numbers[i][j]; /* get the subtracting factor */ temp = projection(ortho, ortho_vector, m->rows); /* expand the matrix */ ortho->columns++; ortho->numbers = realloc(ortho->numbers, sizeof(double *)*ortho->columns); ortho->numbers[ortho->columns - 1] = ortho_vector; vector_subtraction(ortho_vector, temp, m->rows); } return ortho; } return NULL; }
/*solution saved in b */ void conjugate_gradient(sparse_matrix A, double *b, int size) { double *x, *r, *p, *Ap, *aux, rnew, rold, alfa; int i; x = (double*) malloc(size*sizeof(double)); r = (double*) malloc(size*sizeof(double)); p = (double*) malloc(size*sizeof(double)); Ap = (double*) malloc(size*sizeof(double)); aux = (double*) malloc(size*sizeof(double)); for (i = 0; i < size; i ++) { x[i] = 0; r[i] = b[i]; p[i] = b[i]; } rold = inner_product(r, r, size); /* result of operations from all void functions used here are stored in the last argument */ while (1) { matrix_vector_product(A, p, Ap); alfa = rold / inner_product(p, Ap, size); /*step length*/ vector_scalar_product(p, alfa, size, aux); vector_sum(x, aux, size, x); vector_scalar_product(Ap, alfa, size, aux); vector_subtraction(r, aux, size, r); rnew = inner_product(r, r, size); if (sqrt(rnew) < E) break; vector_scalar_product(p, rnew / rold, size, p); vector_sum(p, r, size, p); rold = rnew; } for (i = 0; i < size; i ++) { b[i] = x[i]; } free(x); free(r); free(p); free(Ap); free(aux); }
/* This function transforms a set of vectors into * an orthonormal set: an orthonormal base */ struct vector * gram_schmidt(struct vector *v, unsigned int n) { struct vector *w; w=malloc(n*sizeof(struct vector)); w[0]=unitary_vector(v[0]); unsigned int i,j; struct vector aux; for (i = 1; i < n; i++) { w[i]=copy_vector(v[i]); for (j = 0; j < i; j++) { aux=projection_along(w[j],v[i]) w[i]=vector_subtraction(w[i],aux); } w[i]=unitary_vector(w[i]); } return w; }
void SCANLINE::Compute_Poly_Normal() {//compute polygon normal, vertices normal and illumination model vector< vector<float> >vertex_normal(world_vertex.size(),vector<float>(3)); vector< vector<float> >temp_Light_Intensity//vertex intensity (world_vertex.size(),vector<float>(3)); vector <float> I_light(3);//light intensity I_light[0] = 0.8;//R I_light[1] = 0.0;//G I_light[2] = 0.0;//B vector <float> Intensity_diffuse(3); vector <float> Intensity_specular(3); vector <float> Intensity_ambient(3); vector <float> poly_vector_1(3); vector <float> poly_vector_2(3); vector <float> poly_normal(3); vector <float> H(3); vector <float> temp_H(3); //calculus H vector_summation(temp_H, vec_light,vec_view); for (int j=0; j<3 ;j++ ) H[j] = temp_H[j]/vector_length(temp_H); ///---Intensity ambient----Ka*I for (int j=0; j<3 ;j++ ) Intensity_ambient[j] = K_ambient*I_light[j]; for(int i=0; i<(int)Poly.size(); i++) {//compute polygon normal vector_subtraction(poly_vector_1, world_vertex[Poly[i][2]-1], world_vertex[Poly[i][1]-1]); vector_subtraction(poly_vector_2, world_vertex[Poly[i][2]-1], world_vertex[Poly[i][3]-1]); //compute 2 vector on one polygon cross_product3D(poly_normal, poly_vector_1, poly_vector_2); //calculus cross product // float temp_length = vector_length(poly_normal); // for (int j=0; j<3 ;j++ )//(normalized) // poly_normal[j] = poly_normal[j]/ temp_length; for(int j=1; j<(int)Poly[i][0]+1 ;j++) {//add normal of neibor polygon to vertex for (int p=0; p<3 ;p++ ) vertex_normal[Poly[i][j]-1][p] += poly_normal[p]; } } for(int i=0; i<(int)vertex_normal.size() ;i++ ) { float temp_length = vector_length(vertex_normal[i]); for (int j=0; j<3 ;j++ ) { //normalize the normal vertex_normal[i][j] = vertex_normal[i][j] / temp_length; ///----------Intensity diffuse----Kd*I*(NL) Intensity_diffuse[j] = K_diffuse*I_light[j]*dot_product3D(vertex_normal[i],vec_light); ///----------Intensity specular----Ks*I*(NH)^n Intensity_specular[j] = K_specular*I_light[j]*pow(dot_product3D(vertex_normal[i],H),8); //---------------sum of all intensity temp_Light_Intensity[i][j]= Intensity_diffuse[j] + Intensity_specular[j] + Intensity_ambient[j]; } } Light_Intensity = temp_Light_Intensity; //Light_Intensity match to vertex index }
void SCANLINE::Compute_pixel_intensity() { vector <float> Intensity_diffuse(3); vector <float> Intensity_specular(3); float cylinder_u,cylinder_v; int shininess = 8; for (int i = 0; i< Ymax ; i++ ) for (int j = 0; j< Xmax; j++ ) { vector<float> pixel_normal(real_pixel[i][j].begin()+2,real_pixel[i][j].begin()+5); vector<float> device_xyz(real_pixel[i][j].begin()+5,real_pixel[i][j].end()); if(vector_length(pixel_normal) == 0) continue; // if(vector_length(device_xyz) == 0) // continue; // datatest<<i<<'\t'<<j; // for(int p = 0; p<(int)pixel_normal.size(); p++) // datatest<<setw(15)<<pixel_normal[p]; // datatest<<endl; vector<float> line_inter(4); compute_invert(device_xyz);//out put xyz in world space vector_subtraction(line_inter, ObjectCenter, device_xyz); // for(int p = 0; p<(int)line_inter.size(); p++) // datatest<<setw(15)<<line_inter[p]; // datatest<<endl; Normalization(line_inter); //normalize the pixel normal Normalization(pixel_normal); ///texture mapping // textureMapping(pixel_normal,cylinder_u,cylinder_v); textureMapping(pixel_normal,cylinder_u,cylinder_v); ///------------------------------- float cos_diffuse = dot_product3D(pixel_normal,vec_light); float cos_specular = pow(dot_product3D(pixel_normal,H_specular), shininess); for (int p = 0; p< 3 ; p++ ) { ///----------Intensity diffuse----Kd*I*(NL) Intensity_diffuse[p] = K_diffuse*I_light[p]*cos_diffuse; ///----------Intensity specular----Ks*I*(NH)^n Intensity_specular[p] = K_specular*I_light[p]*cos_specular; //---------------sum of all intensity-- //replace normal value to RGB value in real_pixel real_pixel[i][j][p+2]= Intensity_diffuse[p] + Intensity_specular[p] + Intensity_ambient[p] +imagePixel[(int)cylinder_v][(int)cylinder_u][p]; if(real_pixel[i][j][p+2] > 1) real_pixel[i][j][p+2] = 1; } } // datatest.close(); }