/********************************************************/ /* */ /* */ /* This method standardizes an edge. */ /* When the method concludes */ /* standard contains the standardized edge */ /* forwardTransform contains the transform from */ /* real world coordinates to the */ /* standardized frame */ /* */ /* We assume the edge class has vertices stored */ /* in Tuple u[3]. */ /* */ /* We assume the edge class has an indexing */ /* method e[i], which returns the i-th vertex of */ /* of edge e. */ /* */ /********************************************************/ standardizeEdge(Edge theEdge,float forwardTransform[], float backwardTransform[]) const { // we assume that the edge is valid; i.e. the vertices are // distinct -- if not this will BOMB! // you need to take care of this somewhere float myMatrix[16]; // we'll use this to store transforms float phi; // angle of rotation Tuple v; // axis of rotation Tuple x(1,0,0); // x axis Edge standard=theEdge; // this stores the standardized // edge glPushMatrix(); // save the current matrix // translate our edge so the first vertex is at the origin standard[1] -= standard[0]; standard[0] = Tuple(0,0,0); // rotate our edge to align it with the x axis // first we find the axis of rotation v // then we find the angle through which we need to rotate phi Tuple w = standard[1]; // set w to the edge w.normalize(); // normalize it if (w != x && w!= -x) { // when w is not on the x-axis // the vector of rotation v is found by taking a cross product of // w and the x-vector v = w.cross(x); v.normalize(); // the angle of rotation is found by taking the arcos of // the dot product of w and x // we then convert to degrees phi = (float) acos((double) w.dot(x)); phi *= 360.f/(2.0f*3.14159f); } else { // when w is on the x-axis v=Tuple(0,1,0); // the axis of rotation is the y-vector if (w == x) // the angle is either 0 or 180 degrees phi=0; else phi = 180; } // have openGL compute the rotation transform and write it into myMatrix glLoadIdentity(); glRotatef(phi,v[0],v[1],v[2]); glGetFloatv(GL_MODELVIEW_MATRIX,myMatrix); // update second vertex -- first won't change int i=1; Tuple tmp(0,0,0); for (int j=0; j<3; j++) { // for each row of the matrix for (int k=0; k<3; k++) { // for each column tmp[j] += myMatrix[j+4*k]*standard[i][k]; // the matrix is column-major } } standard[i]=tmp; // correct for rounding errors -- standard[1][1]=0; standard[1][2]=0; // now compute the single forward (standardizing) transform glLoadIdentity(); glRotatef(phi,v[0],v[1],v[2]); glTranslatef(-theEdge->u[0][0],-theEdge->u[0][1], -theEdge->u[0][2]); glGetFloatv(GL_MODELVIEW_MATRIX,forwardTransform); glPopMatrix(); // restore current matrix }