// A.11 implement with virtual tracking ball Cube Body Rotation Program /* Rotating cube demo with trackball */# include <math. h> # include <Gl/glut. h> # include <stdlib. h> # define bool int # define false 0 # define true 1 # define m_pi 3.14int winwidth, winheight; float angle = 0.0, axis [3], Trans [3]; bool trackingmouse = false; bool redrawcontinue = false; bool trackballmove = false;/* draw the cube */glfloat vertices [] [3] = {-1.0,-1.0, -1.0}, {1.0,-1.0,-1.0}, {1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0}, {-1.0,-1.0, 1.0}, {1.0,-1.0, 1.0}, {1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0 }}; glfloat colors [] [3] = {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0}, {0.0, 1.0, 0.0 },{ 0.0, 0.0, 1.0 },{ 1.0, 0.0, 1.0 },{ 1.0, 1.0, 1.0 },{ 0.0, 1.0, 1.0 }}; void polygon (int A, int B, int C, int D, int face) {/* draw a polygon via list of vertices */glbegin (gl_polygon ); glcolor3fv (colors [a]); glvertex3fv (vertices [a]); glvertex3fv (vert ICES [B]); glvertex3fv (vertices [c]); glvertex3fv (vertices [d]); glend ();} void colorcube (void) {/* map vertices to faces */polygon (, 0); polygon (, 1); polygon (, 2); polygon, 5, 1, 3); polygon (, 6, 7, 4); polygon (, 5 );} /* These functions implement a simple trackball-like motion control */float lastpos [3] = {0.0f, 0.0f, 0.0f}; int curx, Cury; int startx, starty; void trackball_pt OV (int x, int y, int width, int height, float V [3]) {float D, a;/* Project X, Y onto a hemisphere centered within width, height */V [0] = (2.0f * X-width)/width; V [1] = (height-2.0f * Y)/height; D = (float) SQRT (V [0] * V [0] + V [1] * V [1]); V [2] = (float) Cos (m_pi/2.0f) * (d <1.0f )? D: 1.0f); a = 1.0f/(float) SQRT (V [0] * V [0] + V [1] * V [1] + V [2] * V [2]); V [0] * = A; V [1] * = A; V [2] * = A;} void mousemotion (int x, int y) {float curpos [3], dx, Dy, DZ; trackball_ptov (X, Y, winwidth, winheight, curpos); If (trackingmouse) {dx = curpos [0]-lastpos [0]; DY = curpos [1]-lastpos [1]; DZ = curpos [2]-lastpos [2]; if (dx | dy | Dz) {angle = 90.0f * SQRT (dx * dx + dy * dy + DZ * Dz); axis [0] = Lastpos [1] * curpos [2]-lastpos [2] * curpos [1]; axis [1] = lastpos [2] * curpos [0]-lastpos [0] * curpos [2]; axis [2] = lastpos [0] * curpos [1]-lastpos [1] * curpos [0]; lastpos [0] = curpos [0]; lastpos [1] = curpos [1]; lastpos [2] = curpos [2];} glupostredisplay ();} void startmotion (int x, int y) {trackingmouse = true; redrawcontinue = false; startx = x; starty = y; curx = x; Cury = y; trackball_ptov (X, Y, winw Idth, winheight, lastpos); trackballmove = true;} void stopmotion (int x, int y) {trackingmouse = false; If (startx! = X | starty! = Y) {redrawcontinue = true;} else {angle = 0.0f; redrawcontinue = false; trackballmove = false;} void display (void) {glclear (gl_color_buffer_bit | gl_depth_buffer_bit ); /* view transform */If (trackballmove) {glrotatef (angle, axis [0], axis [1], axis [2]);} colorcube (); fig ();} void mousebutton (INT button, int state, int X, int y) {If (Button = fig) Exit (0); If (Button = fig) switch (state) {Case glu_down: Y = winheight-y; startmotion (x, y); break; Case glu_up: stopmotion (x, y); break ;}} void myreshape (int w, int h) {glviewport (0, 0, W, H); winwidth = W; winheight = H;} void spincube () {If (redrawcontinue) glupostredisplay ();} int main (INT argc, char ** argv) {gluinit (& argc, argv); gluinitdisplaymode (glu_double | glu_rgb | glu_depth); gluinitwindowsize (500,500 ); valley createwindow ("colorcube"); fig (myreshape); fig (Display); glutidlefunc (spincube); fig (mousebutton ); glmatrixmode (gl_projection); glloadidentity (); glortho (-2.0, 2.0,-2.0, 2.0,-2.0, 2.0); glmatrixmode (gl_modelview); glumainloop ();}