/* Kelcy Monday khm_uk@hotmail.com HON 301, Lee */ #include //used for input/output #include //used for system pause #include //used for formatting #include //used for strings #include //used for file input/output #include //used for math functions using namespace std; #define DEBUG 0 // '1' to enable to get diagnostic printing, '0' to disable #define TESTING 0 // '1' to enable to use hard-coded inputs, '0' to disable // STRUCTURE CREATED TO STORE LINKED-LIST typedef struct point_pair { float *pt1; float *pt2; struct point_pair *next; } POINT_PAIR; // FUNCTION WHICH CALCULATES THE DISTANCE BETWEEN POINTS static float dist_between_pts( float *pt1, float *pt2, int dim) { int i; float dist, sum; sum = 0; for (i = 0; (i < dim); ++i) sum += pow(pt1[i] - pt2[i], 2); dist = sum / dim; return(sqrt(dist)); } // FUNCTION WHICH TAKE THE DOT PRODUCT OF TWO VECTORS static float dot_product( float *vec1, float *vec2, int dim) { float sum; int i; sum = 0; for (i = 0; (i < dim); ++i) sum += vec1[i] * vec2[i]; return(sum); } // FUNCTION WHICH CALCULATES THE MAGNITUDE OF A VECTOR static float calc_magnitude( float *vec, int dim) { return(sqrt(dot_product(vec, vec, dim))); } // FUNCTION WHICH TAKES THE CROSS PRODUCT OF TWO VECTORS static void cross_product( float *vec1, float *vec2, int dim, float *result) { int i; float sum; //takes the cross-product to find the third vector if (dim == 3) { result[0] = vec1[1]*vec2[2] - vec1[2]*vec2[1]; result[1] = vec1[2]*vec2[0] - vec1[0]*vec2[2]; result[2] = vec1[0]*vec2[1] - vec1[1]*vec2[0]; } } #if DEBUG cout << "Cross product():" << endl; cout << " Vec1 "; for (i = 0; (i < dim); ++i) cout << " " << vec1[i]; cout << endl; cout << " Vec2 "; for (i = 0; (i < dim); ++i) cout << " " << vec2[i]; cout << endl; cout << " Result "; for (i = 0; (i < dim); ++i) cout << " " << result[i]; cout << endl; cout << endl; #endif static void unit_vector( float *vec, int dim, float *result) { float magnitude; int i; magnitude = calc_magnitude(vec, dim); if (magnitude == 0) { for (i = 0; (i < dim); ++i) result[i] = vec[i]; return; } for (i = 0; (i < dim); ++i) result[i] = vec[i] / magnitude; } #if TESTING static void set_data_for_testing1( int *dim, int *points, int *newdim) { *dim = 3; *points = 4; *newdim = 3; } static void set_data_for_testing2( float *ptarray) { ptarray[0] = 100; ptarray[1] = 200; ptarray[2] = 3; ptarray[3] = 110; ptarray[4] = 200; ptarray[5] = 3; ptarray[6] = 110; ptarray[7] = 210; ptarray[8] = 3; ptarray[9] = 100; ptarray[10] = 210; ptarray[11] = 3; } static void set_data_for_testing3( float *plane) { plane[0] = 100; plane[1] = 200; plane[2] = 3; } #endif int main() { // open output filestream string filename; ofstream outfile; filename = "data.inc"; outfile.open(filename.c_str()); int dim, newdim, points, i = 0; float dist; #if TESTING set_data_for_testing1(&dim, &points, &newdim); #else cout << "Welcome to Kelcy's Orthogonal Projection Program!" << endl; cout << endl; cout << "This program can project regular polyhedra from either " << endl; cout << "four or three dimensions to three or two dimensions."; cout << endl; cout << endl; cout << endl; cout << "What is the dimension of the object you would like to project? "; cin >> dim; cout << "How many dimensions would you like to project onto? "; cin >> newdim; cout << "How many vertex points do you have? "; cin >> points; cout << endl; #endif int x = points * dim; float ptarray[x]; #if TESTING set_data_for_testing2(ptarray); #else cout << "Please enter the points as a continuous string of " << endl; cout << "numbers, separated only by spaces as such: " << endl; cout << "x1 y1 z1 x2 y2 z2 x3 y3 z3 etc..." << endl; cout << "Note: Please give the first two vertices as " << endl; cout << "vertices joined by an edge. " << endl; cout << endl; cin >> ptarray[i]; i++; //inputs coordinates into an array while (i < x) { cin >> ptarray[i]; i++; } #endif #if DEBUG cout << "Input data:" << endl; for (i = 0; (i < points * dim); ++i) cout << " " << i << ": " << ptarray[i] << endl; cout << endl; #endif // store data into matrix int j, k; int num_of_vertices = x / dim; float actual_dist; float matrix[num_of_vertices][dim]; for (i = k = 0; (i < num_of_vertices); ++i) for (j = 0; (j < dim); ++j) matrix[i][j] = ptarray[k++]; #if DEBUG cout << "Matrix data:" << endl; for (i = 0; (i < num_of_vertices); ++i) { cout << " " << i << ":"; for (j = 0; (j < dim); ++j) cout << " " << matrix[i][j]; cout << endl; } cout << endl; #endif // calculate actual LENGTH of one side actual_dist = dist_between_pts(matrix[0], matrix[1], dim); POINT_PAIR *pair_list = NULL; POINT_PAIR *pair_element; POINT_PAIR pp1; // Now find all pairs of connected points, and store each // pair in the linked list for (j = 0; (j < num_of_vertices); ++j) { // find points connected to first point for (i = j+1; (i < num_of_vertices); ++i) if (dist_between_pts(matrix[j], matrix[i], dim) == actual_dist) { // point j and point i are connected // create a new POINT_PAIR element pair_element = (POINT_PAIR *)malloc(sizeof(POINT_PAIR)); memset(pair_element, 0, sizeof(POINT_PAIR)); pair_element->pt1 = matrix[j]; pair_element->pt2 = matrix[i]; // ADD the element to our linked list pair_element->next = pair_list; pair_list = pair_element; } } #if DEBUG cout << "Pairs of connected points:" << endl; for (pair_element = pair_list; (pair_element); pair_element = pair_element->next) { cout << " ("; for (i = 0; (i < dim); ++i) cout << " " << pair_element->pt1[i]; cout << ") and ("; for (i = 0; (i < dim); ++i) cout << " " << pair_element->pt2[i]; cout << ")" << endl; } cout << endl; #endif float plane[dim]; i = 0; #if TESTING set_data_for_testing3(plane); #else cout << endl; cout << "Please enter the coefficients of the plane you would" << endl; cout << "like to project onto, separated only by spaces." << endl; cout << "Note: please enter the coefficients for all " << " dimensions."; cout << endl; cin >> plane[i]; //inputs coefficients into an array i++; while (i < dim) { cin >> plane[i]; i++; } #endif #if DEBUG cout << "Plane data:" << endl; for (i = 0; (i < dim); ++i) cout << " " << i << ": " << plane[i] << endl; cout << endl; #endif float w[newdim], u[newdim], v[newdim], t[newdim]; if (dim == 3) { w[0] = plane[0]; w[1] = plane[1]; w[2] = plane[2]; u[0] = plane[1]; u[1] = -plane[0]; u[2] = 0; //takes the CROSS-PRODUCT to find the third vector cross_product(u, w, dim, v); } else if (dim == 4) { w[0] = plane[0]; w[1] = plane[1]; w[2] = plane[2]; w[3] = plane[3]; u[0] = w[3]; u[1] = w[2]; u[2] = -w[1]; u[3] = -w[0]; v[0] = -w[2]; v[1] = w[3]; v[2] = w[0]; v[3] = -w[1]; t[0] = w[1]; t[1] = -w[0]; t[2] = w[3]; t[3] = -w[2]; } //declare matrices to hold projection vectors float u_matrix[1][dim]; float v_matrix[1][dim]; float t_matrix[1][dim]; //calculates unit vectors if (dim == 3) { unit_vector(w, dim, w); unit_vector(u, dim, u); unit_vector(v, dim, v); //store vectors into matrices for (i = 0; (i < dim); ++i) { u_matrix[1][i] = u[i]; v_matrix[1][i] = v[i]; } } else if (dim == 4) { unit_vector(w, dim, w); unit_vector(u, dim, u); unit_vector(v, dim, v); unit_vector(t, dim, t); //store vectors into matrices for (j = 0; (j < dim); ++j) { u_matrix[1][j] = u[j]; v_matrix[1][j] = v[j]; t_matrix[1][j] = t[j]; } } // Matrix to hold projected points float new_matrix[num_of_vertices][dim]; // inputs paired vertices from the linked-list into a matrix if (dim == 3) { i = 0; for (pair_element = pair_list; (pair_element); pair_element = pair_element->next) { new_matrix[i][0] = pair_element->pt1[0]; new_matrix[i][1] = pair_element->pt1[1]; new_matrix[i][2] = pair_element->pt1[2]; i++; new_matrix[i][0] = pair_element->pt2[0]; new_matrix[i][1] = pair_element->pt2[1]; new_matrix[i][2] = pair_element->pt2[2]; } } else if (dim == 4) { i = 0; for (pair_element = pair_list; (pair_element); pair_element = pair_element->next) { new_matrix[i][0] = pair_element->pt1[0]; new_matrix[i][1] = pair_element->pt1[1]; new_matrix[i][2] = pair_element->pt1[2]; new_matrix[i][3] = pair_element->pt1[3]; i++; new_matrix[i][0] = pair_element->pt2[0]; new_matrix[i][1] = pair_element->pt2[1]; new_matrix[i][2] = pair_element->pt2[2]; new_matrix[i][3] = pair_element->pt2[3]; } } if (dim == 3) { for (i = 0; (i < num_of_vertices); ++i) { new_matrix[i][0] = dot_product(new_matrix[i],u_matrix[0],dim); i++; new_matrix[i][1] = dot_product(new_matrix[i],v_matrix[0],dim); } } else if (dim == 4) { for (i = 0; (i < num_of_vertices); ++i) { new_matrix[i][0] = dot_product(new_matrix[i], u_matrix[0], dim); i++; new_matrix[i][1] = dot_product(new_matrix[i], v_matrix[0], dim); i++; new_matrix[i][2] = dot_product(new_matrix[i], t_matrix[0], dim); } } // OUTPUTS new points to screen /* for (i=0; (i < num_of_vertices); ++i) { cout << "(" << new_matrix[i][0] << "," << new_matrix[i][1] << ")"; cout << endl; } */ // OUTPUTS new points to "data.inc" file if (dim == 3) { outfile << "#declare p = array[" << num_of_vertices << "] { " << endl; for (i = 0; (i < num_of_vertices); ++i) { outfile << "<" << new_matrix[i][0] << ","; outfile << new_matrix[i][1] << ">" << endl; } outfile << "}"; outfile << endl; outfile << "#declare r=.03;" << endl; outfile << "union{" << endl; for (i = 0; (i < num_of_vertices); ++i) { outfile << "cylinder { "; outfile << "p[" << i << "]" << ", "; i++; outfile << "p[" << i << "]" << ", "; outfile << "r }"; outfile << endl; } outfile << "texture {T_Gold_1A}}" << endl; outfile << endl; } if (dim == 4) { outfile << "#declare p = array[" << num_of_vertices << "] { " << endl; for (i = 0; (i < num_of_vertices); ++i) { outfile << "<" << new_matrix[i][0] << ","; outfile << new_matrix[i][1] << "," ; outfile << new_matrix[i][2] << ">" << endl; } outfile << "}"; outfile << endl; outfile << "#declare r=.03;" << endl; outfile << "union{" << endl; for (i = 0; (i < num_of_vertices); ++i) { outfile << "cylinder { "; outfile << "p[" << i << "]" << ", "; i++; outfile << "p[" << i << "]" << ", "; outfile << "r }"; outfile << endl; } outfile << "texture {T_Gold_1A}" << endl; outfile << "}" << endl; } outfile.close(); //close filestream system("PAUSE"); }