CUGL  2.0
cugl.h
Go to the documentation of this file.
1 #ifndef CUGL_H
2 #define CUGL_H
3 
4 /** \file cugl.h
5  * Concordia University Graphics Library
6  *
7  * \authors Peter Grogono
8 */
9 
10 /** \mainpage Introduction
11 
12  The \c operator<< overloads for classes Point, Quaternion, and Matrix
13  use the current settings of format parameters. \c setw() determines
14  the width of each number rather than the entire field width.
15 
16  Most of the classes do not have copy constructors or \c operator= overloads
17  because the default versions generated by the compiler do the right
18  thing (for once). (Class PixelMap is an exception, because it has
19  pointer members.)
20 
21  \c GLfloat is used as the representation type for most floating-point values.
22  This is for compatibility with OpenGL. Although OpenGL provides a choice of
23  precision for vertex and normal data, matrices are provided in \c GLfloat form only.
24  Single-precision floating-point provides only about six decimal places, but this
25  is sufficient for most graphics calculations. If the number of points, vectors,
26  or matrices used is large, substantial amounts of memory may be saved.
27 
28  Acknowledgements: Mark Kilgard, Ken Shoemake, F.S. Hill, and others, for
29  various publications on mthematical techniques for graphics and OpenGL, and to
30  Liping Ye for improving various features, especially bitmaps.
31 */
32 
33 /** Extensions
34  * \todo Quaternion += and -=
35  * \todo Matrix operator*=(Matrix) - done
36  * \todo bool isVisible(Point) - harder than it looks
37  */
38 
39 #ifdef __APPLE__
40 #include <OpenGL/gl.h>
41 #include <OpenGL/glu.h>
42 #include <GLUT/glut.h>
43 #else
44 #ifdef _WIN32
45  #include <windows.h>
46 #endif
47 #include <GL/gl.h>
48 #include <GL/glu.h>
49 #include <GL/glut.h>
50 #endif
51 
52 #include <iostream>
53 #include <cmath>
54 
55 namespace cugl
56 {
57 
58 /** \defgroup constants Constants */
59 
60 //@{
61 
62 /** A string giving the version of CUGL and the most recent build date. */
63 const char version[] = "CUGL V2 2009.11.24";
64 
65 /** A well-known mathematical constant. */
66 const double PI = 4 * atan(1.0);
67 
68 // End of constants
69 //@}
70 
71 /** The type of OpenGL projection and model view matrices.
72  * It is tempting to write CUGL as a template llibrary, but the fixed type
73  * of OpenGL matrices makes this difficult to do effectively. */
74 typedef GLfloat GL_Matrix[4][4];
75 
76 /** \defgroup errors Error messages */
77 
78 //@{
79 
80 /** Enumeration values for CUGL function errors. */
82 {
83  NO_ERROR = 0, /**< No error has occurred since the error flag was reset. */
84  BAD_INDEX, /**< Encountered an invalid array index. */
85  BAD_MATRIX_MODE, /**< The matrix mode was not GL_PROJECTION or GL_MODELVIEW. */
86  BAD_ROTATION_MATRIX, /**< The given matrix was not a rotation matrix. */
87  SINGULAR_MATRIX, /**< The matrix is singular. */
88  ZERO_DIVISOR, /**< An attempt was made to divide by zero. */
89  ZERO_NORM, /**< An attempt was made to normalize a null vector. */
90  BAD_INTERPOLATOR_ARG, /**< The angle between the rotations of the interpolator is zero. */
91  OPEN_FAILED, /**< The program failed to open a BMP file. */
92  NOT_BMP_FILE, /**< The file opened was not a BMP file. */
93  NOT_24_BITS, /**< The BMP file was not in 24-bit format. */
94  COMPRESSED_BMP_FILE, /**< The BMP file was in compressed form. */
95  NOT_ENOUGH_MEMORY, /**< There is not enough memory to store the pixel map. */
96  NO_PIX_MAP, /**< There is no pixel map to draw. */
97  BAD_PLANE, /**< Parameters do not define a plane. */
98  BAD_LINE, /**< The line lies in the plane. */
99  TOO_MANY_MATERIALS, /**< Too many materials. */
100  TOO_MANY_POINTS /**< Too many points. */
101 };
102 
103 /**
104  * Set code to \c NO_ERROR and return last error code.
105  * \return the most recent error code.
106  */
108 
109 /** Map error codes to descriptive strings.
110  * \param err is an error code obtained from \c getError().
111  * \return A string describing the eeror.
112  */
113 const char *getErrorString(CUGLErrorType err);
114 
115 /**
116  * Display a message if an CUGL error has occurred.
117  * This function checks the CUGL error status.
118  * If no error has occurred, it has no effect.
119  * If CUGL has reported an error, this function writes
120  * the CUGL error code and the corresponding message
121  * to the stream \c cerr.
122  *
123  * Since \c getError() clears the CUGL error flag,
124  * after calling this function CUGL shows no errors.
125  *
126  * This function is intended mainly for development and
127  * should not normally be included in a production program.
128  */
130 
131 /**
132  * Display a message if an OpenGL error has occurred.
133  * This function checks the OpenGL error status.
134  * If no error has occurred, it has no effect.
135  * If OpenGL has reported an error, this function writes
136  * the OpenGL error code and the corresponding message
137  * to the stream \c cerr.
138  *
139  * Since \c glGetError() clears the OpenGL error flag,
140  * after calling this function OpenGL shows no errors.
141  *
142  * This function is intended mainly for development and
143  * should not normally be included in a production program.
144  */
146 
147 // End of error messages
148 //@}
149 
150 
151 
152 // Forward declarations.
153 class Line;
154 class Plane;
155 class Vector;
156 class Quaternion;
157 
158 
159 
160 /**
161  * An instance is a point represented by four homogeneous coordinates.
162  * A point is represented by \a (x,y,z,w) in which each component is a \c GLfloat.
163  * If \a w=0, the point is `at infinity'. Points at infinity may be used like other
164  * points, but a few operations do not work for them. CUGL functions do not issue an
165  * error message when this happens: they simply return a default result.
166  *
167  * A Point is in normal form if \a w=1. A Point may be normalized if \a w!=0.
168  */
169 class Point
170 {
171 public:
172  friend class Line;
173  friend class Vector;
174  friend class Matrix;
175  friend class Plane;
176 
177  /**
178  * Construct a point with coordinates (x, y, z, w).
179  * Default parameter values: (0,0,0,1).
180  */
181  Point(GLfloat x = 0, GLfloat y = 0, GLfloat z = 0, GLfloat w = 1);
182 
183  /**
184  * Construct a Point from coordinates.
185  * \param coordinates is an array containing at least four coordinates.
186  * \pre The array must have at least four components.
187  */
188  Point (GLfloat coordinates[]);
189 
190  /**
191  * Convert a Quaternion to a Point.
192  * \note This is a rather peculiar operation and should not normally be used.
193  * It is intended for experiments with non-linear transformations.
194  * \param q is a quaternion.
195  */
196  Point (const Quaternion & q);
197 
198  /**
199  * Access coordinates of a point.
200  * \param i is the index of the coordinate: p[0] = x, p[1] = y, p[2] = z, p[3] = w.
201  * \note Error BAD_INDEX reported if \c i is not one of {0,1,2, 3}.
202  */
203  GLfloat & operator[](int i);
204 
205  /**
206  * Access coordinates of a point.
207  * This form is used with \c const instances (\c p[i] cannot appear on the left of \c =).
208  * \param i is the index of the coordinate: p[0] = x, p[1] = y, p[2] = z, p[3] = w.
209  * \note Error BAD_INDEX reported if \c i is not one of {0,1,2, 3}.
210  */
211  const GLfloat & operator[](int i) const;
212 
213  /**
214  * Normalize a point.
215  * A Point \a (x,y,z,w) is in normal form if \a w=1.
216  * \note Error ZERO_DIVISOR reported if \a w=0.
217  * \note The value of this Point is changed by this function.
218  */
219  void normalize();
220 
221  /**
222  * Return the normalized form of a Point.
223  * A Point \a (x,y,z,w) is in normal form if \a w=1.
224  * \note Error ZERO_DIVISOR reported if \a w=0.
225  */
226  Point unit() const;
227 
228  /**
229  * Draw the point using \c glVertex4f().
230  */
231  void draw() const;
232 
233  /**
234  * Use this point as a light position.
235  * If w = 0, the light is directional, otherwise it is positional.
236  * \param lightNum specifies which light to use: \a GL_LIGHT0, \a GL_LIGHT1, ...
237  */
238  void light(GLenum lightNum) const;
239 
240  /**
241  * Translate to the point using \c glTranslatef().
242  * \note If the point is at infinity (w = 0), this function has no effect.
243  */
244  void translate() const;
245 
246  /**
247  * Scale a Point.
248  * Scale the coordinates of a Point by dividing by the scalar \a s.
249  * This is implemented by multiplying the \a w component of the Point
250  * by \a s. If \a s=0, the result is a Point at infinity.
251  * \return the Point at \a (x,y,z,s*w).
252  */
253  Point operator/(GLfloat s) const;
254 
255  /**
256  * Displace a Point with a Vector.
257  * The components of the Vector are added to the corresponding components of the Point.
258  * If the Point is not in normal form, the Vector is implicitly scaled.
259  * \return Point at (x-w*v.x, y-w*v.y, z-w*v.z, w).
260  */
261  Point operator+=(const Vector & v);
262 
263  /**
264  * Displace a Point with a Vector
265  * The components of the Vector are subtracted from the corresponding components of the Point.
266  * If the Point is not in normal form, the Vector is implicitly scaled.
267  * \return Point at (x+w*v.x, y+w*v.y, z+w*v.z, w).
268  */
269  Point operator-=(const Vector & v);
270 
271  /**
272  * Displace a Point with a Vector.
273  * The components of the Vector are added to the corresponding components of the Point.
274  * If the Point is not in normal form, the Vector is implicitly scaled.
275  * \return Point at (p.x+p.w*v.x, p.y+p.w*v.y, p.z+p.w*v.z, p.w).
276  */
277  friend Point operator+(const Vector & v, const Point & p);
278 
279  /**
280  * Displace a Point with a Vector.
281  * The components of the Vector are added to the corresponding components of the Point.
282  * If the Point is not in normal form, the Vector is implicitly scaled.
283  * \return Point at (p.x+p.w*v.x, p.y+p.w*v.y, p.z+p.w*v.z, p.w).
284  */
285  friend Point operator+(const Point & p, const Vector & v);
286 
287  /**
288  * Scale a point.
289  * \return Point at (p.x + p.w*v.x, p.y + p.w*v.y, p.z + p.w*v.z).
290  */
291  friend Point operator*(const Point & p, GLfloat s);
292 
293  /**
294  * Scale a point.
295  * Multiply each of the components of the Point by s.
296  * In homogeneous coordinates, this operation does not change the ``position'' of the Point.
297  * However, it may be used, for example, to normalize a Point.
298  * \return The scaled Point.
299  */
300  friend Point operator*(GLfloat s, const Point & p);
301 
302  /**
303  * Return the vector corresponding to the displacement between the two points.
304  * This is the vector (\c p.x/p.w - \c q.x/q.w, \c p.y/p.w - \c q.y/q.w, \c p.z/p.w - \c q.z/q.w).
305  * If \c p or \c q is a point at infinity, return the zero vector.
306  * \return the Vector corresponding to the displacement between the two points.
307  */
308  friend Vector operator-(const Point & p, const Point & q);
309 
310  /**
311  * Find the point where this line meets the plane p.
312  * Sets error BAD_LINE if the line lies within the plane.
313  * \return the Point at which Line \c k meets Plane \c p.
314  */
315  friend Point meet(const Line & k, const Plane & p);
316 
317  /**
318  * Compare two points.
319  * This function returns \c true only if corresponding components are exactly equal.
320  * Values that are theoretically equal but computed in different ways are likely
321  * to be unequal according to this function.
322  */
323  friend bool operator==(const Point & p, const Point & q);
324 
325  /**
326  * Compare two points.
327  * This function returns \c false only if corresponding components are exactly equal.
328  * Values that are theoretically equal but computed in different ways are likely
329  * to be unequal according to this function.
330  */
331  friend bool operator!=(const Point & p, const Point & q);
332 
333  /**
334  * Write "(x,y,z,w)" to output stream.
335  * Inserts the coordinates of the point into the output stream \c os
336  * in the format "(x,y,z,w)". The current settings of the stream formatting
337  * parameters are used. If a width is specified with \c setw(), it is applied
338  * to each coordinate, not to the point as a whole.
339  */
340  friend std::ostream & operator<<(std::ostream & os, const Point & p);
341 
342  /**
343  * Return the distance between a Point and a Plane.
344  * The result has the correct magnitude only if the Point and the Plane
345  * are both in normal form. In particular, the result is incorrect if
346  * the Point is at infinity. However, the sign of the result is correct
347  * in all cases, and so it is not necessary to provide normalized
348  * arguments if only the sign is important.
349  */
350  friend GLfloat dist(const Point & p, const Plane & s);
351 
352  /**
353  * Return the distance between a Point and a Plane.
354  * The result has the correct magnitude only if the Point and the Plane
355  * are both in normal form. In particular, the result is incorrect if
356  * the Point is at infinity. However, the sign of the result is correct
357  * in all cases, and so it is not necessary to provide normalized
358  * arguments if only the sign is important.
359  */
360  friend GLfloat dist(const Plane & s, const Point & p);
361 
362  /**
363  * Return the disgtance bewteen two points.
364  * \note Does not check that the points are normalized.
365  */
366  friend double dist(const Point & p, const Point & q)
367  {
368  return sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y) + (p.z - q.z) * (p.z - q.z));
369  }
370 
371 private:
372 
373  /** X coordinate of point. */
374  GLfloat x;
375 
376  /** Y coordinate of point. */
377  GLfloat y;
378 
379  /** Z coordinate of point. */
380  GLfloat z;
381 
382  /** W coordinate of point. */
383  GLfloat w;
384 
385 };
386 
387 
388 /**
389  * An instance is a line defined by two Points.
390  * Lines are occasionally useful. For example, it is simple to
391  * display surface normals using this class.
392  * A Line is represented by the two Points which are its end-points.
393  */
394 
395 class Line
396 {
397 public:
398 
399  friend class Plane;
400 
401  /**
402  * Construct the Line from Point \c p to Point \c q.
403  */
404  Line(const Point & p, const Point & q);
405 
406  /**
407  * Construct the Line from Point \c p to Point \c p+v.
408  */
409  Line(const Point & p, const Vector & v);
410 
411  /**
412  * Find the point where this line meets the plane p.
413  */
414  friend Point meet(const Line & k, const Plane & p);
415 
416  /**
417  * Draw the line using \c glBegin(GL_LINE) ....
418  */
419  void draw() const;
420 
421  /**
422  * Compare two lines.
423  * This function returns \c true only if corresponding components are exactly equal.
424  * Values that are theoretically equal but computed in different ways are likely
425  * to be unequal according to this function.
426  */
427  friend bool operator==(const Line & x, const Line & y);
428 
429  /**
430  * Compare two lines.
431  * This function returns \c false only if corresponding components are exactly equal.
432  * Values that are theoretically equal but computed in different ways are likely
433  * to be unequal according to this function.
434  */
435  friend bool operator!=(const Line & x, const Line & y);
436 
437  /**
438  * Write a representation of the line to the output stream.
439  * The format is \a pt->pt where "\a pt" is the format used for points.
440  * If \c setw is used to set the width, it is passed to the inserter
441  * for Point.
442  */
443  friend std::ostream & operator<<(std::ostream & os, const Line & k);
444 
445 private:
446  /** Start point of line. */
448 
449  /** Finish point of line. */
450  Point f; // finish point
451 };
452 
453 
454 /**
455  * An instance is a plane defined by its equation \a Ax+By+Cz+D=0.
456  *
457  * Planes are used for clipping, shadows, and reflections
458  * (see class Matrix).
459  *
460  * Homogeneous points (x,y,z,w) lie on the plane if Ax+By+Cz+Dw=0.
461  * The notation for a plane is \a <A,B,C,D>. The plane \a <0,0,0,D> is undefined.
462  * An attempt to construct such a plane sets the error flag to BAD_PLANE and the
463  * plane is set to <0,1,0,0> (in the conventional OpenGL frame, this often corresponds
464  * to the ground, \a y=0).
465  *
466  * A Plane is in normal form if the Vector \a (A,B,C) is a unit vector.
467  * A Plane can be normalized by scaling \a A,B,C,D.
468  */
469 
470 class Plane
471 {
472  friend class Matrix;
473 
474 public:
475  /**
476  * Construct a plane given the coefficients of its equation \a Ax+By+Cx+D=0.
477  * If no arguments are provided, construct the plane y = 0.
478  */
479  Plane(GLfloat a = 0, GLfloat b = 1, GLfloat c = 0, GLfloat d = 0);
480 
481  /**
482  * Construct a plane containing the three given points.
483  */
484  Plane(const Point & p, const Point & q, const Point & r);
485 
486  /**
487  * Construct a plane containing the line \c s and the point \c p.
488  */
489  Plane(const Line & s, const Point & p);
490 
491  /**
492  * Construct the plane orthogonal to \c v and passing through \c p.
493  */
494  Plane(const Vector & v, const Point & p);
495 
496  /**
497  * Normalize this plane.
498  * The Plane \a (A,B,C,D) is in normal form when \a (A,B,C) is a unit vector.
499  * Error ZERO_DIVISOR reported if \a |(A,B,C|=0 (which should not be the case for a well-formed plane).
500  * \note The value of the Plane is changed by this function.
501  */
502  void normalize();
503 
504  /**
505  * Return a normalized Plane equivalent to this plane.
506  * The Plane \a (A,B,C,D) is in normal form when \a (A,B,C) is a unit vector.
507  * Error ZERO_DIVISOR reported if \a |(A,B,C|=0 (which should not be the case for a well-formed plane).
508  */
509  Plane unit() const;
510 
511  /**
512  * Return a vector of unit length that is normal to the plane.
513  */
514  Vector normal() const;
515 
516  /**
517  * Use this plane as a clipping plane.
518  * This function calls \c glClipPlane
519  * to suppress rendering of objects on one side of the plane.
520  * \param index must be one of GL_CLIP_PLANE0, GL_CLIP_PLANE1, ... A
521  * An implementation of OpenGL is supposed to provide at least six
522  * clipping planes, numbered 0,1,...,5.
523  */
524  void clipPlane(GLenum index) const;
525 
526  /**
527  * Find the point where this line meets the plane p.
528  */
529  friend Point meet(const Line & k, const Plane & p);
530 
531  /**
532  * Compare two planes.
533  * This function returns \c true only if corresponding components are exactly equal.
534  * Values that are theoretically equal but computed in different ways are likely
535  * to be unequal according to this function.
536  */
537  friend bool operator==(const Plane & x, const Plane & y);
538 
539  /**
540  * Compare two planes.
541  * This function returns \c false only if corresponding components are exactly equal.
542  * Values that are theoretically equal but computed in different ways are likely
543  * to be unequal according to this function.
544  */
545  friend bool operator!=(const Plane & x, const Plane & y);
546 
547  /**
548  * Write a description of the plane to the output stream as \a <a,b,c,d>.
549  * Inserts the components of the plane into the output
550  * stream \c os in the format \a <a,b,c,d>. The current settings
551  * of the stream formatting parameters are used. If a width
552  * is specified with \c setw(), it is applied to each component
553  * rather than to the plane as a whole.
554  */
555  friend std::ostream & operator<<(std::ostream & os, const Plane & p);
556 
557  /**
558  * Return the distance between a Point and a Plane.
559  * The result has the correct magnitude only if the Point and the Plane
560  * are both in normal form. In particular, the result is incorrect if
561  * the Point is at infinity. However, the sign of the result is correct
562  * in all cases, and so it is not necessary to provide normalized
563  * arguments if only the sign is important.
564  */
565  friend GLfloat dist(const Point & p, const Plane & s);
566 
567  /**
568  * Return the distance between a Point and a Plane.
569  * The result has the correct magnitude only if the Point and the Plane
570  * are both in normal form. In particular, the result is incorrect if
571  * the Point is at infinity. However, the sign of the result is correct
572  * in all cases, and so it is not necessary to provide normalized
573  * arguments if only the sign is important.
574  */
575  friend GLfloat dist(const Plane & s, const Point & p);
576 
577  /** Return the A component of the plane defined by Ax+By+Cz+d=0. */
578  GLfloat getA() { return a; }
579 
580  /** Return the B component of the plane defined by Ax+By+Cz+d=0. */
581  GLfloat getB() { return b; }
582 
583  /** Return the C component of the plane defined by Ax+By+Cz+d=0. */
584  GLfloat getC() { return c; }
585 
586  /** Return the D component of the plane defined by Ax+By+Cz+d=0. */
587  GLfloat getD() { return d; }
588 
589 
590 private:
591  /** Coefficient of \a x in the plane equation. */
592  GLfloat a;
593 
594  /** Coefficient of \a y in the plane equation. */
595  GLfloat b;
596 
597  /** Coefficient of \a z in the plane equation. */
598  GLfloat c;
599 
600  /** Coefficient of \a w in the plane equation. */
601  GLfloat d;
602 };
603 
604 class Matrix;
605 
606 /**
607  * An instance is a vector with 3 real components.
608  * A vector v is a 3-vector represented by three orthogonal components
609  * \a vx, \a vy, and \a vz. The norm of the vector \a v is vx*vx+vy*vy+vz*vz.
610  * The length of \c v is \c sqrt(norm(v)).
611  */
612 class Vector
613 {
614  friend class Point;
615  friend class Matrix;
616  friend class Quaternion;
617 
618 public:
619  /**
620  * Construct the zero vector: (0,0,0).
621  */
622  Vector() : x(0), y(0), z(0)
623  {}
624 
625  /**
626  * Construct the vector (x,y,z).
627  */
628  Vector(GLfloat x, GLfloat y, GLfloat z)
629  : x(x), y(y), z(z)
630  {}
631 
632  /**
633  * Construct a vector from the array \c coordinates.
634  * \pre The array must have at least three components.
635  */
636  Vector(GLfloat coordinates[]);
637 
638  /**
639  * Construct a vector normal to the polygon defined
640  * by the given points using Martin Newell's algorithm.
641  * The normal vector will be exact if the points lie in a plane,
642  * otherwise it will be a sort of average value. As with OpenGL,
643  * the vector will point in the direction from which the points
644  * are enumerated in a counter-clockwise direction.
645  *
646  * Unlike other functions, this function does \b not use homogeneous coordinates.
647  * The points are assumed to have (x,y,z) coordinates; the w component is ignored.
648  * \param points is an array of points.
649  * \param numPoints is the number of points in the array.
650  * \return the vector normal to the plane defined by \a points.
651  * \note The vector is \b not a unit vector because it will probably
652  * be averaged with other vectors.
653  */
654  Vector(Point points[], int numPoints);
655 
656  /**
657  * Construct a vector from two points.
658  * Vector(p, q) is equivalent to p - q.
659  */
660  Vector(const Point & p, const Point & q);
661 
662  /**
663  * Construct a vector from a quaternion by ignoring the scalar component of the quaternion.
664  * Vector(q) constructs the vector returned by \c q.vector().
665  * \param q is the \a Quaternion whose vector component is to be used.
666  */
667  explicit Vector(const Quaternion & q);
668 
669  /**
670  * Add vector \c v to this vector.
671  */
672  Vector operator+=(const Vector & v);
673 
674  /**
675  * Subtract vector \c v from this vector.
676  */
677  Vector operator-=(const Vector & v);
678 
679  /**
680  * Return Vector (-x,-y,-z).
681  */
682  Vector operator-() const;
683 
684  /**
685  * Multiply each component of the vector by \c scale.
686  */
687  Vector operator*=(GLfloat scale);
688 
689  /**
690  * Return the vector (x/scale,y/scale,z/scale).
691  * Error ZERO_DIVISOR reported if \c scale is zero.
692  * \return the Vector (x/scale,y/scale,z/scale).
693  */
694  Vector operator/(GLfloat scale) const;
695 
696  /**
697  * Divide each component of this vector by \c scale and return the new value.
698  * Error ZERO_DIVISOR reported if \c scale is zero.
699  */
700  Vector operator/=(GLfloat scale);
701 
702  /**
703  * Normalize this vector.
704  * See also \a Vector::unit().
705  * Reports error ZERO_NORM if the vector is zero.
706  * \note The value of this vector is changed by this operation.
707  */
708  void normalize();
709 
710  /**
711  * Return a unit vector with the same direction as this vector.
712  * See also \a Vector::normalize().
713  * Reports error ZERO_NORM if the vector is zero.
714  * \note The value of this vector is not changed by this operation.
715  */
716  Vector unit() const;
717 
718  /**
719  * Return the norm of this vector.
720  * The norm of a vector is the sum of its squared components
721  * and is also the square of the length.
722  * \return the norm of this vector.
723  */
724  GLfloat norm() const;
725 
726  /**
727  * Return the length of this vector.
728  * The length of a vector is the square root of its norm.
729  * \return the length of this vector.
730  */
731  GLfloat length() const;
732 
733  /**
734  * Use this vector to translate an object.
735  * This is implemented by passing the vector to \c glTranslate().
736  */
737  void translate() const;
738 
739  /**
740  * Use this vector as a normal vector when drawing a surface.
741  * This is implemented by passing the vector to \c glNormal().
742  */
743  void drawNormal() const;
744 
745  /**
746  * Construct the skew-symmetric matrix corresponding to this vector.
747  */
748  Matrix skew();
749 
750  /**
751  * Draw this vector as a line in the graphics window.
752  * The line joins \a P and \a P+V, where \a P is the point provided,
753  * or the origin if no point is given.
754  * \param p is the start point for the vector.
755  */
756  void draw(const Point & p = Point()) const;
757 
758  /**
759  * Get or set a reference to a component of this vector.
760  * \c v[0] is the \a x component; \c v[1] is the \a y component; \c v[2] is the \a z component.
761  * Error BAD_INDEX reported if \c i is not one of 0, 1, 2.
762  */
763  GLfloat & operator[](int i);
764 
765  /**
766  * Get a reference to a component of this vector.
767  * This form is used for \c const instances (\c v[i] cannot appear on the left of \c =).
768  * \c v[0] is the \a x component; \c v[1] is the \a y component; \c v[2] is the \a z component.
769  * Error BAD_INDEX reported if \c i is not one of 0, 1, 2.
770  */
771  const GLfloat & operator[](int i) const;
772 
773  /**
774  * Return cross product of vectors \c u and \c v.
775  */
776  friend Vector cross(const Vector & u, const Vector & v);
777 
778  /**
779  * Return cross product of vectors \c u and \c v.
780  */
781  friend Vector operator*(const Vector & u, const Vector & v);
782 
783  /**
784  * Return dot product of vectors \c u and \c v.
785  */
786  friend GLfloat dot(const Vector & u, const Vector & v);
787 
788  /**
789  * Return Vector \a s*v.
790  */
791  friend Vector operator*(const Vector & v, GLfloat s);
792 
793  /**
794  * Return Vector \a s*v.
795  */
796  friend Vector operator*(GLfloat s, const Vector & v);
797 
798  /**
799  * Return Vector \a u+v.
800  */
801  friend Vector operator+(const Vector & u, const Vector & v);
802 
803  /**
804  * Return Vector \a u-v.
805  */
806  friend Vector operator-(const Vector & u, const Vector & v);
807 
808  /**
809  * Displace a Point with a Vector.
810  * \return Point at (p.x+p.w*v.x, p.y+p.w*v.y, p.z+p.w*v.z, p.w).
811  */
812  friend Point operator+(const Vector & v, const Point & p);
813 
814  /**
815  * Return Point \c p displaced by vector \c v.
816  */
817  friend Point operator+(const Point & p, const Vector & v);
818 
819  /**
820  * Compare two vectors.
821  * This function returns \c true only if corresponding components are exactly equal.
822  * Values that are theoretically equal but computed in different ways are likely
823  * to be unequal according to this function.
824  */
825  friend bool operator==(const Vector & x, const Vector & y);
826 
827  /**
828  * Compare two vectors.
829  * This function returns \c false only if corresponding components are exactly equal.
830  * Values that are theoretically equal but computed in different ways are likely
831  * to be unequal according to this function.
832  */
833  friend bool operator!=(const Vector & x, const Vector & y);
834 
835  /**
836  * Write vector to output stream as \a (x,y,z).
837  * Inserts the components of the vector into the output
838  * stream \c os in the format \a (x,y,z). The current settings
839  * of the stream formatting parameters are used. If a width
840  * is specified with \c setw(), it is applied to each coordinate,
841  * not to the vector as a whole.
842  */
843  friend std::ostream & operator<<(std::ostream & os, const Vector & v);
844 
845 private:
846 
847  /** X component of vector. */
848  GLfloat x;
849 
850  /** Y component of vector. */
851  GLfloat y;
852 
853  /** Z component of vector. */
854  GLfloat z;
855 };
856 
857 /**
858  * Unit vector parallel to \a X axis.
859  */
860 const Vector I(1, 0, 0);
861 
862 /**
863  * Unit vector parallel to \a Y axis.
864  */
865 const Vector J(0, 1, 0);
866 
867 
868 /**
869  * Unit vector parallel to \a Z axis.
870  */
871 const Vector K(0, 0, 1);
872 
873 /**
874  * An instance is a matrix compatible with an OpenGL transformation matrix.
875  * An instance of class Matrix is a 4 by 4 matrix with
876  * components of type \c GLfloat. The components are ordered
877  * in the same way as an OpenGL matrix (column-row order,
878  * for compatibility with FORTRAN).
879 
880  * Note that OpenGL performs matrix calculations very efficiently.
881  * As far as possible, construct transformations using sequences of
882  * OpenGL matrix operations. Construct and use the matrices here
883  * only if OpenGL does not provide the required facilities.
884  */
885 class Matrix
886 {
887 public:
888 
889  /**
890  * Construct the identity matrix.
891  */
893 
894  /**
895  * Construct a copy of an arbitrary OpenGL matrix.
896  */
898 
899  /**
900  * Construct a copy of an OpenGL projection or model view matrix.
901  \param mode should be \c GL_PROJECTION_MATRIX or \c GL_MODELVIEW_MATRIX.
902 
903  Report error BAD_MATRIX_MODE and construct identity matrix
904  for other values of mode.
905  */
906  explicit Matrix(GLenum mode);
907 
908  /**
909  * Construct a rotation matrix.
910  \param axis is the axis of rotation.
911  \param theta is the magnitude of the rotation.
912  \note The angle \c theta should be in radians (unlike OpenGL, which uses degrees).
913  */
914  Matrix(const Vector & axis, double theta);
915 
916  /**
917  * Construct a matrix that reflects a point in the given plane.
918  * The matrix can be used to simulate a mirror in an OpenGL program.
919  * See also Matrix::reflect().
920  \param refl is the plane of reflection.
921  */
922  explicit Matrix(const Plane & refl);
923 
924  /**
925  * Construct a shadow matrix from a point light source and a plane.
926  * The matrix transforms an object into its shadow on the given plane.
927  * It is your job to ensure that the shadow has the appropriate colour, transparency, etc.
928  * The light source may be a local point (w > 0) or a point at infinity (w = 0).
929  * See also \c Matrix::shadow().
930  \param lightPos is the position of the light source.
931  \param plane is the plane onto which the shadow is projected.
932 
933  */
934  Matrix(const Point & lightPos, const Plane & plane);
935 
936  /**
937  * Construct a rotation matrix from a quaternion.
938  * \pre The quaternion must be a unit quaternion.
939  */
940  explicit Matrix(const Quaternion & q);
941 
942  /**
943  * Construct the matrix that rotates one vector to another.
944  * \param u is a vector representing an initial orientation.
945  * \param v is a vector representing the final orientation.
946  * The matrix, applied to \a u, will yield \a v.
947  * \pre The vectors \a u and \a v must be unit vectors.
948  */
949  Matrix(const Vector & u, const Vector & v);
950 
951  /**
952  * Construct a matrix from 16 floats.
953  */
954  Matrix(
955  const GLfloat m00, const GLfloat m10, const GLfloat m20, const GLfloat m30,
956  const GLfloat m01, const GLfloat m11, const GLfloat m21, const GLfloat m31,
957  const GLfloat m02, const GLfloat m12, const GLfloat m22, const GLfloat m32,
958  const GLfloat m03, const GLfloat m13, const GLfloat m23, const GLfloat m33 );
959 
960  /**
961  * Return the quaternion corresponding to this matrix.
962  * This function may report BAD_ROTATION_MATRIX.
963  * \note The result may be imprecise if the rotation angle is close to 180 degrees.
964  * \pre The matrix must be a rotation matrix.
965  */
967 
968  /**
969  * Return a pointer to the first element of the matrix.
970  * This function may be used in conjunction with
971  * \c glMultMatrix() to apply this matrix to the current OpenGL matrix.
972  * \return a pointer to the first element of the matrix.
973  */
974  GLfloat *get()
975  ;
976 
977  /**
978  * Return the transpose of this matrix.
979  */
980  Matrix transpose() const;
981 
982  /**
983  * Return the trace of this matrix.
984  * The trace will include the bottom right element, m[3][3].
985  */
986  GLfloat trace()
987  {
988  return m[0][0] + m[1][1] + m[2][2] + m[3][3];
989  }
990 
991  /**
992  * Compute the inverse of this matrix using Gauss-Jordan elimination.
993  * If the matrix is singular, report \c SINGULAR_MATRIX and return the zero matrix.
994  * Calculations are performed in double precision because this gives
995  * slightly better results.
996  * The prefix operator ~ has the same effect.
997  * \return the inverse of this matrix.
998  */
999  Matrix inv() const;
1000 
1001  /**
1002  * Return the inverse of this matrix.
1003  * This provides an alternative syntax for inv().
1004  * \return the inverse of this matrix.
1005  */
1006  Matrix operator~() const;
1007 
1008  /**
1009  * Multiply the current OpenGL matrix by this matrix.
1010  */
1011  void apply() const;
1012 
1013  /**
1014  * Apply this matrix to a point.
1015  */
1016  Point apply(const Point & p) const;
1017 
1018  /**
1019  * Apply this matrix to a vector.
1020  */
1021  Vector apply(const Vector & v) const;
1022 
1023  /**
1024  * Return the axis of a rotation matrix.
1025  * Report error \c BAD_ROTATION_MATRIX and leave result undefined,
1026  * if the matrix is not a rotation.
1027  * \return the axis of a rotation matrix.
1028  */
1029  Vector axis() const;
1030 
1031  /**
1032  * Return the angle (in radians) of a rotation matrix.
1033  * Report error \c BAD_ROTATION_MATRIX and leave result undefined,
1034  * if the matrix is not a rotation.
1035  * \return the angle (in radians) of a rotation matrix.
1036  */
1037  double angle() const;
1038 
1039  /**
1040  * Return a reference to the element \c m[i][j] of the matrix.
1041  * \pre The values of \c i and \c j must be in the range [0,3].
1042  * \return the element \c m[i][j] of the matrix.
1043  */
1044  GLfloat & operator()(int i, int j);
1045 
1046  /**
1047  * Return a reference to the element \c m[i][j] of the \c const matrix.
1048  * This version is used for \c const instances (\c m(i,j) cannot appear on the left of \c =).
1049  * \pre The values of \c i and \c j must be in the range [0,3].
1050  * \return the element \c m[i][j] of the matrix.
1051  */
1052  const GLfloat & operator()(int i, int j) const;
1053 
1054  /**
1055  * Set the matrix so that it reflects a point in the plane \c p.
1056  * The matrix can be used to simulate a mirror in an OpenGL program.
1057  * See also constructors for class Matrix.
1058  \param p is the plane of reflection.
1059  */
1060  void reflect(const Plane & p);
1061 
1062  /**
1063  * Set the matrix so that it creates a shadow on the plane \c p from a light source \c lightPos.
1064  * The matrix transforms an object into its shadow on the given plane.
1065  * It is your job to ensure that the shadow has the appropriate colour, transparency, etc.
1066  * The point \c p may be either a local point (w > 0) or a point at infinity (w = 0).
1067  * See also constructors for class Matrix.
1068  \param lightPos is the position of the light source causing the shadow.
1069  \param plane is the plane upon which the shadow is cast.
1070  */
1071  void shadow(const Point & lightPos, const Plane & plane);
1072 
1073  /** Add and assign matrices. */
1074  Matrix operator+=(const Matrix & rhs);
1075 
1076  /** Add two matrices. */
1077  friend Matrix operator+(const Matrix & m, const Matrix & n);
1078 
1079  /** Subtract and assign matrices. */
1080  Matrix operator-=(const Matrix & rhs);
1081 
1082  /** Subtract two matrices. */
1083  friend Matrix operator-(const Matrix & m, const Matrix & n);
1084 
1085  /** Multiply and assign matrices. */
1086  Matrix operator*=(const Matrix & rhs);
1087 
1088  /** Multiply two matrices. */
1089  friend Matrix operator*(const Matrix & m, const Matrix & n);
1090 
1091  /** Multiply scalar and matrix. */
1092  friend Matrix operator*(GLfloat s, const Matrix & m);
1093 
1094  /** Multiply matrix and scalar. */
1095  friend Matrix operator*(const Matrix & m, GLfloat s);
1096 
1097  /** Multiply by scalar and assign. */
1098  Matrix & operator*=(GLfloat s);
1099 
1100  /** Divide by scalar and assign. */
1101  Matrix & operator/=(GLfloat s);
1102 
1103  /** Divide by scalar. */
1104  friend Matrix operator/(const Matrix & m, GLfloat s);
1105 
1106  /**
1107  * Compare two matrices.
1108  * This function returns \c true only if corresponding components are exactly equal.
1109  * Values that are theoretically equal but computed in different ways are likely
1110  * to be unequal according to this function.
1111  */
1112  friend bool operator==(const Matrix & x, const Matrix & y);
1113 
1114  /**
1115  * Compare two matrices.
1116  * This function returns \c false only if corresponding components are exactly equal.
1117  * Values that are theoretically equal but computed in different ways are likely
1118  * to be unequal according to this function.
1119  */
1120  friend bool operator!=(const Matrix & x, const Matrix & y);
1121 
1122  /**
1123  * Write a four-line image of the matrix to the output stream.
1124  * The current settings of the stream formatting parameters are used.
1125  * If a width is specified with \c setw(), it is applied to each
1126  * element of the matrix, not the matrix as a whole.
1127  */
1128  friend std::ostream & operator<<(std::ostream & os, const Matrix & m);
1129 
1130 private:
1131 
1132  /** The elements of the matrix. */
1134 };
1135 
1136 
1137 
1138 /**
1139  * An instance is a quaternion represented as a (scalar, vector) pair.
1140  * We use the notation \a (s,v) for a quaternion with scalar component
1141  * \a s and vector component \a v. Although arbitrary quaternions can be
1142  * constructed, all of the applications of quaternions provided by
1143  * the class assume that the quaternion is a unit quaternion
1144  * representing a rotation.
1145  */
1147 {
1148 public:
1149 
1150  friend class Vector;
1151  friend class Matrix;
1152 
1153  /**
1154  * Construct the quaternion (1,(0,0,0)) (the null rotation).
1155  */
1156  Quaternion() : s(1)
1157  {}
1158 
1159  /**
1160  * Construct the quaternion (s, (x,y,z)).
1161  */
1162  Quaternion(GLfloat s, GLfloat x, GLfloat y, GLfloat z)
1163  : s(s), v(Vector(x,y,z))
1164  {}
1165 
1166  /**
1167  * Construct the quaternion \a (0,v).
1168  * The result will be a unit quaternion if \a v is a unit vector,
1169  * in which case the quaternion represents a rotation through
1170  * 90 degrees about the axis \a v.
1171  */
1172  Quaternion(const Vector & v) : s(0), v(v)
1173  {}
1174 
1175  /**
1176  * Construct the quaternion \a (s,v).
1177  * \note Don't confuse this constructor with Quaternion(axis,angle).
1178  * \param s is the scalar component of the quaternion.
1179  * \param v is the vector component of the quaternion.
1180  */
1181  Quaternion(GLfloat s, const Vector & v) : s(s), v(v)
1182  {}
1183 
1184  /**
1185  * Construct a quaternion with the given axis of rotation and angle.
1186  * \note Don't confuse this constructor with Quaternion(s,v).
1187  * \pre The axis must be a unit vector.
1188  * \param axis gives the axis of rotation.
1189  * \param angle gives the amount of the rotation.
1190  */
1192  : s(GLfloat(cos(angle/2))), v(GLfloat(sin(angle/2)) * axis)
1193  {}
1194 
1195  /**
1196  * Construct the quaternion corresponding to an OpenGL rotation matrix.
1197  * The result may be imprecise if the rotation angle is close to 180 degrees.
1198  * This function may report BAD_ROTATION_MATRIX.
1199  * \pre The matrix must be a rotation matrix.
1200  */
1202 
1203  /**
1204  * Construct a quaternion from Euler angles.
1205  */
1206  Quaternion(double xr, double yr, double zr);
1207 
1208  /**
1209  * Construct a Quaternion from a Point.
1210  * The quaternion consists of the vector \a (p[0],p[1],p[2]) and the scalar \a p[3].
1211  * \note This is a unusual operation and should not normally be used.
1212  * It is intended for experiments with non-linear transformations.
1213  */
1214  Quaternion(const Point & p);
1215 
1216  /**
1217  * Construct the quaternion that rotates one vector to another.
1218  * \param u is a vector representing an initial orientation.
1219  * \param v is a vector representing the final orientation.
1220  * The quaternion, applied to \a u, will yield \a v.
1221  * \pre The vectors \a u and \a v must be unit vectors.
1222  */
1223  Quaternion(const Vector & u, const Vector & v);
1224 
1225  /**
1226  * Add the quaternion q to this quaternion.
1227  */
1228  Quaternion operator+=(const Quaternion & q);
1229 
1230  /**
1231  * Subtract the quaternion q from this quaternion.
1232  */
1233  Quaternion operator-=(const Quaternion & q);
1234 
1235  /**
1236  * Return the quaternion \a q+r.
1237  * \note The sum of two unit quaternions is not in general a unit quaternion.
1238  * However, it occasionally appears in expressions such as k q1 + (1 - k) q2,
1239  * which does yield a unit quaternion.
1240  * \return the Quaternion \a q+r.
1241  */
1242  friend Quaternion operator+(const Quaternion & q, const Quaternion & r);
1243 
1244  /**
1245  * Return the quaternion \a q-r.
1246  * \note The difference of two unit quaternions is not in general a unit quaternion.
1247  * \return the Quaternion \a q-r.
1248  */
1249  friend Quaternion operator-(const Quaternion & q, const Quaternion & r);
1250 
1251  /**
1252  * Return the quaternion product \a q*r.
1253  * If \c q and \c r represent
1254  * rotations, then \a q*r represents the rotation \a q followed by the rotation \a r.
1255  * \note Quaternion multiplication is not commutative: \a q*r is not equal to \a r*q.
1256  * \return the Quaternion product \a q*r.
1257  */
1258  friend Quaternion operator*(const Quaternion & q, const Quaternion & r);
1259 
1260  /**
1261  * Promote the vector \a v to a quaternion \a qv and
1262  * return the quaternion product \a qv*q.
1263  */
1264  friend Quaternion operator*(const Vector & v, const Quaternion & q);
1265 
1266  /**
1267  * Promote the vector \a v to a quaternion \a qv and
1268  * return the quaternion product \a q*qv.
1269  */
1270  friend Quaternion operator*(const Quaternion & q, const Vector & v);
1271 
1272  /** REMOVED: ambiguous operattion - need left and right quotients.
1273  * Return the quaternion ratio \a q/r.
1274  * If q and r represent
1275  * rotations, then \a q/r represents the rotation \a q followed by
1276  * the rotation that is the inverse of \a r.
1277  * \return the Quaternion ratio \a q/r.
1278  */
1279  // friend Quaternion operator/(const Quaternion & q, const Quaternion & r);
1280 
1281  /**
1282  * Multiply this quaternion by \c q and return the result.
1283  */
1284  Quaternion & operator*=(const Quaternion & q);
1285 
1286  /**
1287  * Divide this quaternion by \c q and return the result.
1288  */
1289  Quaternion & operator/=(const Quaternion & q);
1290 
1291  /**
1292  * Return the quaternion \a a*q, where \a a is a scalar.
1293  * \a a is a scalar and a*(s,v) = (a*s, a*v).
1294  * \return the Quaternion \a a*q.
1295  */
1296  friend Quaternion operator*(const Quaternion & q, GLfloat a);
1297 
1298  /**
1299  * Multiply by scalar and assign.
1300  */
1301  Quaternion & operator*=(GLfloat s);
1302 
1303  /**
1304  * Divide by scalar and assign.
1305  */
1306  Quaternion & operator/=(GLfloat s);
1307 
1308  /**
1309  * Return the quaternion \a a*q, where \a a is a scalar.
1310  * \a a is a scalar and a*(s,v) = (a*s, a*v).
1311  * \return the Quaternion \a a*q.
1312  */
1313  friend Quaternion operator*(GLfloat a, const Quaternion & q);
1314 
1315  /**
1316  * Return the quaternion \a q/a, where \a a is a scalar.
1317  * \a a is a scalar and (s,v)/a = (s/a, v/a).
1318  * Report error ZERO_DIVISOR if \a a = 0.
1319  * \return the Quaternion \a q/a.
1320  */
1321  Quaternion operator/(GLfloat scale) const;
1322 
1323  /**
1324  * Normalize this quaternion.
1325  * See also Quaternion::unit().
1326  * Report error ZERO_DIVISOR if q = (0,(0,0,0)).
1327  * \note The value of this quaternion is changed by this operation.
1328  */
1329  void normalize();
1330 
1331  /**
1332  * Return a unit quaternion corresponding to this quaternion.
1333  * See also Quaternion::normalize().
1334  * Report error ZERO_DIVISOR if q = (0,(0,0,0)).
1335  * \note The value of this quaternion is not changed by this operation.
1336  */
1337  Quaternion unit() const;
1338 
1339  /**
1340  * Return the conjugate of this quaternion.
1341  * The conjugate of (s,v) is (s,-v).
1342  * The inverse and conjugate of a unit quaternion are equal.
1343  * \return the conjugate of this quaternion.
1344  */
1345  Quaternion conj() const;
1346 
1347  /**
1348  * Return Inverse of this quaternion.
1349  * q.inv() = q.conj()/q.norm().
1350  * The inverse and conjugate of a unit quaternion are equal.
1351  * Report error ZERO_DIVISOR if q.norm() = 0.
1352  * If \c q represents a rotation then \c q.inv() represents
1353  * the opposite, or inverse, rotation.
1354  * The prefix operator ~ has the same effect.
1355  * \return the inverse of this quaternion.
1356  */
1357  Quaternion inv() const;
1358 
1359  /**
1360  * Return Inverse of this quaternion.
1361  * This provides alternative syntax for \c inv().
1362  * \return the inverse of this quaternion.
1363  */
1364  Quaternion operator~() const;
1365 
1366  /**
1367  * Apply this quaternion to the vector \c w.
1368  * The vector \c w is not changed.
1369  * \return the rotated vector \c q.inv()*w*q.
1370  */
1371  Vector apply(const Vector & w) const;
1372 
1373  /**
1374  * Return Vector component \a v of the quaternion \a q = \a (s,v).
1375  * The same effect can be achieved with the constructor \c Vector::Vector(q).
1376  */
1377  Vector vector() const;
1378 
1379  /**
1380  * Return Scalar component \a s of the quaternion \a q = \a (s,v).
1381  */
1382  GLfloat scalar() const;
1383 
1384  /**
1385  * Return the norm of this quaternion.
1386  * The norm is the sum of the squared components
1387  * and is also the square of the magnitude.
1388  * \return the norm of this quaternion.
1389  */
1390  GLfloat norm() const;
1391 
1392  /**
1393  * Return the magnitude of this quaternion.
1394  * The magnitude is the square root of the norm.
1395  * \return the magnitude of this quaternion.
1396  */
1397  GLfloat magnitude() const;
1398 
1399  /**
1400  * Compute the rotation matrix corresponding to this quaternion
1401  * and store it in the Matrix \c m.
1402  */
1403  void matrix(Matrix & m) const;
1404 
1405  /**
1406  * Compute the rotation matrix corresponding to this quaternion
1407  * and store it in the OpenGL matrix \c m.
1408  */
1409  void matrix(GL_Matrix m) const;
1410 
1411  /**
1412  * Apply the current quaternion to the current OpenGL matrix.
1413  */
1414  void apply() const;
1415 
1416  /**
1417  * Return the axis of rotation of this quaternion.
1418  * \pre The quaternon must be a unit quaternion.
1419  * \return a unit vector giving the axis of rotation of the quaternion.
1420  */
1421  Vector axis() const;
1422 
1423  /**
1424  * Return the amount of rotation of this quaternion.
1425  * \pre The quaternon must be a unit quaternion.
1426  * \return the amount of rotation provided by this quaternion in radians.
1427  */
1428  double angle() const;
1429 
1430  /**
1431  * Integrate an angular velocity vector.
1432  * The rotation represented by this quaternion will be updated by
1433  * applying the angular velocity \c omega for a short interval of
1434  * time \c dt.
1435  * \param omega is an angular velocity vector.
1436  * \param dt is the time increment for integration.
1437  */
1438  void integrate(const Vector & omega, double dt);
1439 
1440  /**
1441  * Return Euler angles for this quaternion.
1442  * The quaternion gives the rotation that would be obtained by calling
1443  * \c glRotatef three times, with arguments (\c xr,1,0,0), (\c yr,0,1,0), and
1444  * (\c zr,0,0,1).
1445  * \pre The angle transformations are applied in \a x, \a y, \a z order.
1446  * \return the Euler angles corresponding to this quaternion.
1447  */
1448  void euler(double & xr, double & yr, double & zr) const;
1449 
1450  /**
1451  * Use this quaternion to simulate a trackball.
1452  * To use this function in an OpenGL program, use the default constructor
1453  * to construct the quaternion \a q = (1,(0,0,0)). In the display function,
1454  * use \c q.rotate() to modify the OpenGL model view matrix.
1455  *
1456  * Call \c trackball(x1,y1,x2,y2) to record a small mouse movement
1457  * from \a (x1,y1) to \a (x2,y2). The coordinates should be normalized
1458  * so that both \a x and \a y are in [-1,1].
1459  *
1460  * This function will compute a rotation will apply this rotation to
1461  * the current quaternion. The rotation simulates a trackball.
1462  */
1463  void trackball(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
1464 
1465  /**
1466  * log(q) of a quaternion is a pure quaternion (scalar part 0).
1467  * log(q) is an element of the Lie algebra of the quaternion group.
1468  * log(1;0) = (0;0).
1469  */
1470  friend Quaternion log(const Quaternion & q)
1471  {
1472  return (q.s == 1) ?
1473  Quaternion(0.0, Vector()) :
1474  Quaternion(0.0, (acos(q.s) / sqrt(1 - q. s * q.s))* q.v);
1475  }
1476 
1477  /**
1478  * exp(q) is defined for pure quaternions (scalar part zero) only.
1479  * (that is, members of the Lie algebra of the quaternion group).
1480  * This function ignores the scalar part - it does not check for zero.
1481  */
1482  friend Quaternion exp(const Quaternion & q)
1483  {
1484  Vector a = q.v;
1485  GLfloat angle = a.length();
1486  return (angle == 0) ?
1487  Quaternion() :
1488  Quaternion(cos(angle), a * sin(angle)/angle);
1489  }
1490 
1491  /**
1492  * exp(v) is a quaternion. The vector is treated as a "pure" quaternion
1493  * (that is, as a member of the Lie algebra of the quaternion group).
1494  */
1495  friend Quaternion exp(const Vector & v)
1496  {
1497  GLfloat angle = v.length();
1498  return (angle == 0) ?
1499  Quaternion() :
1500  Quaternion(cos(angle), v * sin(angle)/angle);
1501  }
1502 
1503 // /**
1504 // * The 'logarithm' of a unit quaternion is a vector.
1505 // * This function is defined because it appears in descriptions of quaternions.
1506 // * Although the name 'ln' is appropriate in some ways, this function must be used with
1507 // * caution because it may not have the properties you expect of a logarithm.
1508 // * For example, \a ln(q1)+ln(q2) makes sense only if \a q1 and \a q2 have the
1509 // * same axis.
1510 // * \pre The quaternion must be a unit quaternion.
1511 // */
1512 // friend Vector ln(const Quaternion & q);
1513 //
1514 // /**
1515 // * The 'exponent' of a vector is a unit quaternion.
1516 // * Although the name 'exp' is appropriate in some ways, this function must be used with
1517 // * caution because it may not have the properties you expect of an exponent.
1518 // * For example, \a exp(v1+v2)=exp(v1)*exp(v2) only if \a v1 and \a v2 have the same
1519 // * direction.
1520 // */
1521 // friend Quaternion exp(const Vector & v);
1522 
1523  /**
1524  * Return the dot product of quaternions \c q and \c r.
1525  * The dot product of \a (s,u) and \a (t,v) is \a st+dot(u,v)
1526  * where \a dot(u,v) denotes the vector dot product of \a u and \a v.
1527  * \return the dot product of quaternions \c q and \c r.
1528  */
1529  friend GLfloat dot(const Quaternion & q, const Quaternion & r);
1530 
1531  /**
1532  * Compare two quaternions.
1533  * This function returns \c true only if corresponding components are exactly equal.
1534  * Values that are theoretically equal but computed in different ways are likely
1535  * to be unequal according to this function.
1536  */
1537  friend bool operator==(const Quaternion & x, const Quaternion & y);
1538 
1539  /**
1540  * Compare two quaternions.
1541  * This function returns \c false only if corresponding components are exactly equal.
1542  * Values that are theoretically equal but computed in different ways are likely
1543  * to be unequal according to this function.
1544  */
1545  friend bool operator!=(const Quaternion & x, const Quaternion & y);
1546 
1547  /**
1548  * Write the quaternion to the output stream as \a s \a (x,y,z).
1549  */
1550  friend std::ostream & operator<<(std::ostream & os, const Quaternion & q);
1551 
1552 private:
1553 
1554  /** Scalar component of quaternion. */
1555  GLfloat s;
1556 
1557  /** Vector component of quaternion. */
1559 };
1560 
1561 
1562 
1563 /**
1564  * An instance represents a camera.
1565  * An instance of class \c Camera is used to control the view.
1566  * The function \c Camera::apply() calls \c gluLookAt() with
1567  * appropriate parameters. The other functions of this class
1568  * set up these parameters.
1569  *
1570  * Camera movements may be smooth (interlpolated between end
1571  * points) or abrupt. The function Camera::setMode() determines
1572  * the kind of movement.
1573  * Smooth transitions are obtained by calling \c Camera::idle()
1574  * in the GLUT idle callback function, together with the various
1575  * camera movement functions.
1576  */
1577 
1578 
1579 
1580 //typedef void (BaseCamera::*IdleMemFunc)();
1581 
1582 //IdleMemFunc gIdleMemFunc;
1583 
1584 /**
1585 * All derived class must implement at least two
1586 * virtual functions \c BaseCamera::idle() which will
1587 * typically be called in the callback function for glutIdleFunc,
1588 * i.e. within callback function "idle()" DerivedClass::idle() will
1589 * be called and later in "main" callback "idle()" will be called
1590 * as parameter to "glutIdleFunc".
1591 * void idle() { DerivedClass::idle();}
1592 * int main() { ... glutIdleFunc(idle); ...}
1593 * \c BaseCamera::apply() const. Similarly inside callback function
1594 * for "glutDisplayFunc", say "display()", DerivedClass::apply() will be
1595 * called.
1596 * i.e. void display() { DerivedClass::apply();..}
1597 * int main(){...glutDisplayFunc(display); ...}
1598 *
1599 */
1600 
1602 {
1603 public:
1604  /** Construct an instance of a \a BaseCamera.
1605  * This constructor is usually called from a subclass.
1606  */
1608  {}
1609 
1610  /**
1611  * Set the number of steps required for a camera movement.
1612  * \param s is the number of steps executed during a movement.
1613  * \a s = 10 will give a rapid, possibly jerky, movement.
1614  * \a s = 100 will give a slow, smooth movement.
1615  */
1616  void setSteps(int s)
1617  {
1618  maxSteps=s;
1619  }
1620 
1621  /**
1622  * This function should be called from the GLUT idle() function
1623  * or its equivalent. It performs one step of the motion until
1624  * the motion is complete, after which it has no effect.
1625  */
1626  virtual void idle()=0;
1627 
1628  /**
1629  * This function should be called from the GLUT display() function
1630  * or its equivalent.
1631  */
1632  virtual void apply() const =0;
1633 
1634  /**
1635  * This function is just a suggested wrapper for all derived class
1636  * for initializations, such as set up first and last position for
1637  * motions in /c Interpolator, or set up new eye and view parameter
1638  * for /c Camera. I don't want to force new class to wrap their
1639  * initialization actions within this function, so, I don't make this
1640  * method as abstract one.
1641  * (added by nick)
1642  */
1643  virtual void update()
1644  {}
1645 
1646 protected:
1647 
1648  /** Current value of step counter. */
1649  int steps;
1650 
1651  /** Maximum number of steps for a smooth movement. */
1653 
1654 };
1655 
1656 
1657 /**
1658  * An instance represents a camera.
1659  * An instance of class \c Camera is used to control the view.
1660  * The function \c Camera::apply() calls \c gluLookAt() with
1661  * appropriate parameters. The other functions of this class
1662  * set up these parameters.
1663  *
1664  * Camera movements may be smooth (interlpolated between end
1665  * points) or abrupt. The function Camera::setMode() determines
1666  * the kind of movement.
1667  * Smooth transitions are obtained by calling \c Camera::idle()
1668  * in the GLUT idle callback function, together with the various
1669  * camera movement functions.
1670  */
1671 class Camera : public BaseCamera
1672 {
1673  //friend void myIdle();
1674 public:
1675 
1676  /**
1677  * Construct a default camera. The view is set as follows:
1678  * Eye = (0,0,1). Model=(0,0,0). Up=(0,1,0).
1679  */
1681 
1682  /**
1683  * Construct a camera for a particular view.
1684  * \param eye sets the eye coordinates for \c gluLookAt().
1685  * \param model sets the model coordinates for \c gluLookAt().
1686  * \param up sets the 'up' vector for \c gluLookAt().
1687  */
1688  Camera(const Point & eye, const Point & model, const Vector & up);
1689 
1690  /**
1691  * Construct a camera for a particular view.
1692  * The 'up' vector is set to (0,1,0).
1693  * \param eye sets the eye coordinates for \c gluLookAt().
1694  * \param model sets the model coordinates for \c gluLookAt().
1695  */
1696  Camera(const Point & eye, const Point & model);
1697 
1698  /**
1699  * Construct a camera for a particular view.
1700  * The 'up' vector is set to (0,1,0).
1701  * The model point is set to (0,0,0).
1702  * \param eye sets the eye coordinates for \c gluLookAt().
1703  */
1704  explicit Camera(const Point & eye);
1705 
1706  /**
1707  * Set the camera for a particular view.
1708  * \param eye sets the eye coordinates for \c gluLookAt().
1709  * \param model sets the model coordinates for \c gluLookAt().
1710  * \param up sets the 'up' vector for \c gluLookAt().
1711  */
1712  void set(const Point & eye, const Point & model, const Vector & up)
1713  ;
1714 
1715  /**
1716  * Set the camera for a particular view.
1717  * The 'up' vector is set to (0,1,0).
1718  * \param eye sets the eye coordinates for \c gluLookAt().
1719  * \param model sets the model coordinates for \c gluLookAt().
1720  */
1721  void set(const Point & eye, const Point & model)
1722  ;
1723 
1724  /**
1725  * Set the camera for a particular view.
1726  * The model point is set to (0,0,0).
1727  * The 'up' vector is set to (0,1,0).
1728  * \param eye sets the eye coordinates for \c gluLookAt().
1729  */
1730  void set(const Point & eye)
1731  ;
1732 
1733 
1734  /**
1735  * Update the camera position.
1736  * This function should be called from the GLUT idle() function
1737  * or its equivalent. It performs one step of the motion until
1738  * the motion is complete, after which it has no effect.
1739  */
1740  virtual void idle();
1741 
1742  /**
1743  * Apply the camera position to the model-view matrix.
1744  * This function calls \c gluLookAt() with appropriate parameters.
1745  * It should be called in the GLUT display function or its equivalent
1746  * after the model-view matrix has been initialized.
1747  */
1748  void apply() const;
1749 
1750  /**
1751  * Move the camera upwards (+Y direction).
1752  * \param distance gives the amount of movement. Negative values move
1753  * the camera downwards.
1754  */
1755  void moveUp(GLfloat distance);
1756 
1757  /**
1758  * Move the camera forwards.
1759  * The camera moves towards the model.
1760  * \param distance gives the amount of movement. Negative values move
1761  * the camera away from the model..
1762  */
1763  void moveForward(GLfloat distance);
1764 
1765  /**
1766  * Move the camera to its left.
1767  * \param distance gives the amount of movement. Negative values move
1768  * the camera to its right.
1769  */
1770  void moveLeft(GLfloat distance);
1771 
1772  /**
1773  * Tilt the camera upwards.
1774  * \param angle gives the angle through which the camera should be moved.
1775  * Negative values give a downward tilt.
1776  */
1777  void tiltUp(double angle);
1778 
1779  /**
1780  * Pan the camera to the left.
1781  * \param angle gives the angle through which the camera should be panned.
1782  * Negative values give panning to the right.
1783  */
1784  void panLeft(double angle);
1785 
1786  /**
1787  * Set the kind of motion required.
1788  * \param mode should be set to \c true for smooth movements
1789  * or to \c false for abrupt movements.
1790  */
1791  void setMode(bool mode)
1792  {
1793  smooth = mode;
1794  }
1795 
1796  /**
1797  * Write a representation of the camera to a stream.
1798  * This function displays the current settings of the eye point,
1799  * the model point, and the up vector.
1800  * \param os is a reference to an output stream.
1801  * \param c is a reference to a camera.
1802  */
1803 
1804  friend std::ostream & operator<<(std::ostream & os, const Camera & c);
1805 
1806 protected:
1807 
1808  /** Update the camera position. */
1809  void update(const Point & e, const Point & m);
1810 
1811  /** Eye coordinates for gluLookAt(). */
1813 
1814  /** Previous eye coordinates. */
1816 
1817  /** Updated eye coordinates. */
1819 
1820 
1821  /** Model coordinates for gluLookAt() */
1823 
1824  /** Previous model coordinates */
1826 
1827  /** Updated model coordinates */
1829 
1830  /** Up vector for gluLookAt() */
1832 
1833  /** Mode for motion */
1834  bool smooth;
1835 };
1836 
1837 /**
1838  * An instance is an interpolator for rotations.
1839  * An instance of Interpolator is used to interpolate between two rotations.
1840  * In other words, given two orientations of an object, an interpolator can
1841  * be used to move the object smoothly from one orientation to the other.
1842  * An interpolator is represented by two quaternions representing the
1843  * extreme values of the rotations. When a real number \a t in the interval
1844  * [0,1] is passed to the interpolator, the interpolator constructs a third
1845  * quaternion representing an intermediate orientation. This quaternion can
1846  * be used to generate a rotation matrix or transform the OpenGL model view.
1847  *
1848  * The simplest way to use this class is as follows:
1849  * -# Construct two quaternions, \a q and \a r, corresponding to the
1850  * first and last positions of the desired movement.
1851  * -# Construct an interpolator \a i(q,r).
1852  * -# In the OpenGL display function, call \c i.apply(t), giving
1853  * \a t a sequence of values ranging from 0 to 1.
1854  *
1855  *
1856  */
1858 {
1859 public:
1860 
1861  /**
1862  * Construct an interpolator with dummy values for the quaternions.
1863  * The interpolator may fail if it is used without first setting the
1864  * start and finish quaternions. Use \c Quaternion::set() to change
1865  * the first and last quaternions to useful values.
1866  */
1868 
1869  /**
1870  * Construct an interpolator to rotate from \c qFirst to \c qLast.
1871  * Report error \c BAD_INTERPOLATOR_ARG if \c qFirst = \c qLast.
1872  */
1873  Interpolator(const Quaternion & qFirst, const Quaternion & qLast);
1874 
1875  /**
1876  * Change the first and last quaternions of an existing interpolator.
1877  * Report error \c BAD_INTERPOLATOR_ARG if \c qFirst = \c qLast.
1878  */
1879  void set(const Quaternion & qFirst, const Quaternion & qLast)
1880  ;
1881 
1882  /**
1883  * Perform the rotation at position \a t, 0 <= \a t <= 1
1884  * by modifying the current OpenGL transformation matrix.
1885  */
1886  void apply(double t) const;
1887 
1888  /**
1889  * Compute the rotation matrix for position \a t, 0 <= \a t <= 1.
1890  */
1891  void getMatrix(double t, GL_Matrix m) const;
1892 
1893  /**
1894  * Return the quaternion for position \a t, 0 <= \a t <= 1.
1895  */
1896  Quaternion getQuaternion(double t) const;
1897 
1898  /**
1899  * Update the Interpolator position.
1900  * This function should be called from the GLUT idle() function
1901  * or its equivalent. It performs one step of the motion until
1902  * the motion is complete, after which it has no effect.
1903  */
1904  virtual void idle();
1905 
1906  /**
1907  * Apply the Interpolator rotation to the model-view matrix.
1908  * This function calls apply(t) with parameters t which is actually steps/maxSteps.
1909  * It should be called in the GLUT display function or its equivalent
1910  * after the model-view matrix has been initialized.
1911  */
1912  virtual void apply() const;
1913 
1914  /**
1915  * Update Interpolator first and last Quaternion.
1916  */
1917  virtual void update()
1918  {
1919  ;
1920  }
1921 
1922 protected:
1923 
1924  /** Initialize the interpolator. */
1925  void initialize();
1926 
1927  /** The quaternion currently in use. */
1929 
1930  /** The start quaternion for the interpolation. */
1932 
1933  /** The final quaternion for the interpolation. */
1935 
1936  /** The angle between the first and last positions. */
1937  double omega;
1938 
1939  /** The sine of the angle between the first and last positions. */
1940  double sinOmega;
1941 
1942  /** The cosine of the angle between the first and last positions. */
1943  double cosOmega;
1944 };
1945 
1946 
1947 
1948 /**
1949  * An instance is an RGB pixel array.
1950  * An instance of PixelMap holds an array that OpenGL can use
1951  * as a texture or to display directly.
1952  *
1953  * This class is implemented so that it does not depend on Windows.
1954  * In principle, it should even work with Linux and other operating
1955  * systems, although this has not been tested thoroughly.
1956  *
1957  * If you want to use a \a BMP image as a texture, the width and height
1958  * must be powers of two. Thus a 256 x 512 \a BMP image is acceptable
1959  * but a 640 x 400 image is not. This restriction does not apply to
1960  * images that are displayed as bitmaps.
1961  *
1962  * Since an instance of \c PixelMap contains pointers, there are memory
1963  * management issues. The destructor deletes pixel and other data
1964  * associated with a pixel map. The copy constructor is declared privately
1965  * and not implemented: this prevents instances being passed by value,
1966  * although they may be passed by reference. Since there is a default
1967  * constructor, you can construct arrays of PixelMap's or pointers to
1968  * PixelMap.
1969  */
1971 {
1972 public:
1973 
1974  /**
1975  * Construct an empty pixel map.
1976  */
1978 
1979  /**
1980  * Read a pixel map from a file.
1981  * \param bmpFileName is a path to a BMP file.
1982  */
1983  PixelMap(const char *bmpFileName);
1984 
1985  /**
1986  * Construct a pixel map from a region of the pixel buffer.
1987  * \param x is the \a X coordinate of the lower left corner of the region.
1988  * \param y is the \a Y coordinate of the lower left corner of the region.
1989  * \param w is the width of the region in pixels.
1990  * \param h is the height of the region in pixels.
1991  * \note See also PixelMap::read(x, y, w, h).
1992  */
1993  PixelMap(GLint x, GLint y, GLsizei w, GLsizei h);
1994 
1995  /**
1996  * Delete a pixel map.
1997  */
1999 
2000  /**
2001  * Read a BMP file and convert it to a pixel map.
2002  * Previous data associated with this object will be deleted.
2003  * The BMP file must satisfy several criteria if it is to
2004  * be converted successfully. Conversion failure is
2005  * indicated by the following CUGL errors.
2006  * \li \c OPEN_FAILED: the file could not be opened
2007  * \li \c NOT_BMP_FILE: the file is not a BMP file
2008  * \li \c NOT_24_BITS: the format is not 24 bits/pixel
2009  * \li \c COMPRESSED_BMP_FILE: the file is compressed
2010  * \li \c NOT_ENOUGH_MEMORY: there is not enough memory to store the data
2011  *
2012  * OpenGL cannot use a bitmap as a texture if its dimensions are not powers of 2.
2013  * To check whether the bitmap has acceptable dimensions, call \c PixelMap::badSize().
2014  * To convert the bitmap dimensions to acceptable values, call \c PixelMap::rescale().
2015  * \param bmpFileName is the name of the file to be read, with the extension '.bmp'.
2016  */
2017  void read(const char *bmpFileName);
2018 
2019  /**
2020  * Read a pixel map from a region of the framebuffer.
2021  * This function is similar to the constructor with the same parameters,
2022  * but allocates new memory only if necessary.
2023  * \param x is the \a X coordinate of the lower left corner of the region.
2024  * \param y is the \a Y coordinate of the lower left corner of the region.
2025  * \param w is the width of the region in pixels.
2026  * \param h is the height of the region in pixels.
2027  * \param mode is passed to glReadBuffer before reading the pixels.
2028  * \note See also the constructor PixelMap(x, y, w, h).
2029  */
2030  void read(GLint x, GLint y, GLsizei w, GLsizei h, GLenum mode = GL_FRONT);
2031 
2032  /**
2033  * Write a pixel map to an output stream as a \a BMP file.
2034  * \param bmpFileName is the name of the file to be written, with the extension '.bmp'.
2035  */
2036  void write(const char *bmpFileName);
2037 
2038  /**
2039  * Check the dimensions of the bit map.
2040  * If the dimensions are not powers of 2, return \c true.
2041  * If the dimensions of the bitmap are not powers of 2,
2042  * OpenGL cannot use it as a texture.
2043  * You should call \c PixelMap::rescale() to resize the bit map.
2044  */
2045  bool badSize();
2046 
2047  /**
2048  * Rescale a bit map whose dimensions are not powers of 2.
2049  * The new image will be distorted; the amount of distortion depends
2050  * on how much the dimensions have to be altered.
2051  * Use \c PixelMap::badSize() to determine whether the dimensions are powers of 2.
2052  */
2053  void rescale();
2054 
2055  /**
2056  * Draw the pixel map at the current raster position.
2057  * Error \c NO_PIX_MAP if there is no pixel map avaialble.
2058  */
2059  void draw();
2060 
2061  /**
2062  * Set texture parameters for the pixel map.
2063  * \param name is an OpenGL index for the texture parameters
2064  * provided by the caller.
2065  * \note This function sets \c GL_TEXTURE_MAG_FILTER and
2066  * \c GL_TEXTURE_MIN_FILTER to \c GL_NEAREST. Call glTexParameter()
2067  * to change these settings.
2068  * \note When this function returns, OpenGL has copied the pixel map
2069  * into its own memory space. It is therefore safe to delete the
2070  * PixelMap instance after calling setTexture().
2071  */
2072  void setTexture(GLuint name);
2073 
2074  /**
2075  * Set texture parameters for the pixel mipmaps.
2076  * Construct a family of mipmaps for texturing.
2077  * \param name is an OpenGL index for the texture parameters
2078  * provided by the caller.
2079  * \note This function sets \c GL_TEXTURE_MIN_FILTER to
2080  * \c GL_LINEAR_MIPMAP_NEAREST. Call glTexParameter()
2081  * to change this setting.
2082  * \note When this function returns, OpenGL has copied the pixel map
2083  * into its own memory space. It is therefore safe to delete the
2084  * PixelMap instance after calling setMipmaps().
2085  * \note Call this function once only for each texture you need in
2086  * your program. Use \c glBindTexture to select textures in the
2087  * display function.
2088  */
2089  void setMipmaps(GLuint name);
2090 
2091  /** Check that two pixel maps are compatible for combining. */
2092  friend bool compatible(const PixelMap & m1, const PixelMap & m2);
2093 
2094  /** Combine two pixel maps.
2095  * \param m1 is the first map to be combined.
2096  * \param m2 is the second map to be combined.
2097  * \param res is the resulting pixel map.
2098  The caller is responsible for constructing this map;
2099  it is not constructed by the function.
2100  \param prop is the mixing proportion: 0 gives m1,
2101  0.5 gives half of each, and 1 gives m2.
2102  */
2103  friend void mix(const PixelMap & m1, const PixelMap & m2, PixelMap & res, double prop);
2104 
2105  /** Select a region from a pixel map.
2106  * \param src is the pixel map from which the data is extracted.
2107  * \param xp defines the left side of the selected region.
2108  * \param yp defines the right side of the selected region.
2109  * \param width is the width of the selected region.
2110  * \param height is the height of the selected region.
2111  */
2112  void select(const PixelMap & src, int xp, int yp, int width, int height);
2113 
2114  /**
2115  * Return number of rows in pixel map.
2116  */
2117  unsigned long getRows() const
2118  {
2119  return numRows;
2120  }
2121 
2122  /**
2123  * Return number of columns in pixel map.
2124  */
2125  unsigned long getColumns() const
2126  {
2127  return numCols;
2128  }
2129 
2130  /**
2131  * Return bytes of memory used by pixel map.
2132  */
2133  unsigned long getSize() const
2134  {
2135  return size;
2136  }
2137 
2138  /**
2139  * Return name of BMP file.
2140  */
2141  char *getName() const
2142  {
2143  return fileName;
2144  }
2145 
2146  /**
2147  * Return \c true if a pixel map has been read successfully.
2148  */
2149  bool ready() const
2150  {
2151  return pixels != 0;
2152  }
2153 
2154  /**
2155  * Write a description of the pixel map to the output stream.
2156  */
2157  friend std::ostream & operator<<(std::ostream & os, const PixelMap & pm);
2158 
2159 private:
2160 
2161  /**
2162  * The copy constructor is private and unimplemented.
2163  * This prevents pixel maps from being copied by mistake.
2164  */
2165  PixelMap(const PixelMap & pm);
2166 
2167  /** Allocate memory for a new pixel map if necessary. */
2168  bool allocate(unsigned long newSize);
2169 
2170  /** Number of rows in the pixel map. */
2171  unsigned long numRows;
2172 
2173  /** Number of columns in the pixel map. */
2174  unsigned long numCols;
2175 
2176  /** Size, in bytes, of the pixel map. */
2177  unsigned long size;
2178 
2179  /** Name of the file used to store the pixel map. */
2180  char *fileName;
2181 
2182  /** Pointer to the pixels of the map. */
2183  unsigned char *pixels;
2184 };
2185 
2186 
2187 /** The type of an array of GLfloats. */
2188 typedef GLfloat* GLfloatArray;
2189 
2190 /**
2191  * An instance is a surface of revolution represented by its profile.
2192 
2193  * The shape of the surface is determined by a 'profile'.
2194  *
2195  * The profile is defined by an array. Each component of the
2196  * array is a pair \a (h,r) in which \a h is measured along
2197  * the axis of revolution and \a r is the distance from the
2198  * axis. (If the axis is assumed to be vertical, then \a h
2199  * suggests 'height' and \a r suggests 'radius'.)
2200  * The surface is generated by rotating the profile
2201  * about the \a Z-axis.
2202  *
2203  * The function \c Revolute::draw() generates
2204  * vertex coordinates, normals, and texture coordinates for the
2205  * surface.
2206  *
2207  * It is up to the caller to set the OpenGL state for rendering:
2208  * this includes setting material properties and defining rules for polygon shading,
2209  * or binding an appropriate texture.
2210  *
2211  * The normals generated by \c Revolute::process() are obtained by averaging
2212  * the normals of the polygons that meet at each vertex. Consequently,
2213  * if \c GL_SMOOTH shading is used and sufficient points and slices are specified,
2214  * the object should look fairly smooth.
2215  */
2217 {
2218 public:
2219  /**
2220  * Construct a surface of revolution.
2221  *
2222  * \param numSteps is the number of coordinates in the profile.
2223  * \param profile is the address of a 2D array giving the points of the profile.
2224  */
2225  Revolute(int numSteps, GLfloat profile[][2]);
2226 
2227  /**
2228  * Delete a surface of revolution.
2229  */
2231 
2232  /**
2233  * Set the number of "slices".
2234  * The value determines the visual quality of the object.
2235  * The number of slices should be an odd number greater than 2.
2236  * If it is not, Revolute::process() will change it.
2237  * By default, the number of slices is 45, corresponding to
2238  * 8 degrees per slice.
2239  * \note After changing the number of slices, you must call
2240  * \c Revolute::process() again before calling \c Revolute::draw().
2241  */
2242  void setSlices(int slices);
2243 
2244  /**
2245  * Set the eccentricity of the surface.
2246  * By default, the eccentricity is 0, giving a surface
2247  * with a circular cross-section. Setting the eccentricity
2248  * to a non-zero value gives a surface with an elliptical
2249  * cross-section. As the eccentricity approaches 1,
2250  * the major axis of the ellipse increases without limit
2251  * as the cross-section approaches a parabola.
2252  * \param ecc must be greater than or equal to zero and
2253  * less than 1.
2254  * \note After changing the eccentricity, you must call
2255  * \c Revolute::process() again before calling \c Revolute::draw().
2256  */
2257  void setEccentricity(double ecc);
2258 
2259  /**
2260  * Compute vertexes, normals, and texture coordinates for the surface of revolution.
2261  * This function must be called \b before calling \c Revolute::draw().
2262  */
2263  void process();
2264 
2265  /**
2266  * Draw the surface of revolution.
2267  * \param showNormals determines whether surface normals will be drawn.
2268  * Note that surface normals are computed for lighting purposes anyway:
2269  * \c showNormals is provided mainly as a debugging aid and should not
2270  * normally be needed.
2271  * \note Revolute::process() must be called before this function.
2272  */
2273  void draw(bool showNormals = false);
2274 
2275 private:
2276 
2277  /**
2278  * The copy constructor is private and not implemented:
2279  * instances cannot be copied implicitly.
2280  */
2281  Revolute(const Revolute &);
2282 
2283  /**
2284  * The assignment operator is private and not implemented:
2285  * instances cannot be assigned.
2286  */
2287  const Revolute& operator=(const Revolute &);
2288 
2289  /** */
2290  int numSteps;
2291 
2292  /** */
2293  int numSlices;
2294 
2295  /** */
2296  double eccentricity;
2297 
2298  /** */
2299  bool ready;
2300 
2301  /** */
2302  GLfloatArray *coor;
2303 
2304  /** */
2305  GLfloat *texCoor;
2306 
2307  /** */
2308  Point *points;
2309 
2310  /** */
2311  Vector *normals;
2312 
2313  /** */
2314  Vector *faceNormals;
2315 };
2316 
2317 
2318 /**
2319  * \defgroup freefun Miscellaneous functions
2320  */
2321 
2322 //@{
2323 
2324 /**
2325  * Convert degrees to radians.
2326  */
2327 inline double radians(double angle)
2328 {
2329  return angle * PI / 180;
2330 }
2331 
2332 /**
2333  * Convert radians to degrees.
2334  */
2335 inline double degrees(double angle)
2336 {
2337  return angle * 180 / PI;
2338 }
2339 
2340 /** Return the square of the argument. */
2341 inline double sqr(double x)
2342 {
2343  return x * x;
2344 }
2345 
2346 /** Return a random integer in [0, max). */
2347 inline unsigned int randInt(unsigned int max)
2348 {
2349  static unsigned int seed = 12345678;
2350  unsigned int result;
2351  const unsigned int bucket = static_cast<unsigned int>(4294967296.0 / max);
2352  do
2353  {
2354  seed = 1664525 * seed + 1013904223;
2355  result = seed / bucket;
2356  }
2357  while (result >= max);
2358  return result;
2359 }
2360 
2361 /** Return a random integer in [-max, max]. */
2362 inline int randSym(unsigned int max)
2363 {
2364  return randInt(2 * max + 1) - max;
2365 }
2366 
2367 /** Return a random double in [0, 1). */
2368 inline double randReal()
2369 {
2370  int BIG = 10000000;
2371  return double(randInt(BIG)) / double(BIG);
2372 }
2373 
2374 /**
2375  * Construct normals for OpenGL triangle strips.
2376  * Given a set of vertexes definining a triangle strip in OpenGL format,
2377  * this functions constructs a normal corresponding to each vertex.
2378  * \param points is an array of points giving the vertex coordinates.
2379  * \param normals is an array of vectors in which the vertex normals will be stored.
2380  * \param numPoints is the number of vertexes provided and the number of normals
2381  * that will be calculated.
2382  * \param neg specifies negated normals, if \a true.
2383  The default is \a false.
2384  * \note To avoid allocation and deallocation overhead, this function uses a
2385  * a fixed amount of workspace that allows up to 100 vertexes to be processed.
2386  * If numPoints > 100, the function will have no effect.
2387  * \note For efficiency, it is better to compute the normals during initialization
2388  * rather than each time the model is displayed.
2389  */
2390 void triStripNormals(Point points[], Vector normals[], int numPoints, bool neg = false);
2391 
2392 /**
2393  * Constructs a surface of revolution.
2394  * Constructs and renders a surface of revolution obtained by rotating
2395  * a curve about the \a Y axis.
2396 
2397  * \param numSteps is the number of points in the array \c coor
2398  * \param coor is the 2D coordinates of points of the profile
2399  * \param numSlices is the number of pie-shaped slices used to render the surface.
2400  * \param drawNormals determines whether normals are generated. By default, normals
2401  * are not generated.
2402 
2403  * For example, if \c numSlices = 20, points will be constructed at 360/20 = 18
2404  * degree intervals.
2405 
2406  * This function constructs an array of points in 3D space and then issues
2407  * calls to \c glVertex(). If \c drawNormals is true, it also issues calls to
2408  * \c glNormal(). The effect of these calls is to define a 3D mesh.
2409  * It is up to the caller to set the OpenGL state for rendering:
2410  * this includes setting material properties and defining rules for polygon shading.
2411 
2412  * The normals generated by \c revolve() are obtained by averaging the normals of the
2413  * polygons that meet at each vertex. Consequently, if \c GL_SMOOTH shading is used
2414  * and enough points are specified, the object should look fairly smooth.
2415 
2416  * \note This function has been replaced by class \c Revolute, which provides more
2417  * functionality and is more efficient.
2418  */
2419 void revolve(int numSteps, GLfloat coor[][2], int numSlices, bool drawNormals = false);
2420 
2421 
2422 
2423 // Additional inline functions for Point and Vector classes.
2424 
2425 /**
2426  * Call gluLookAt() looking at the origin of the model (0,0,0)
2427  * with 'up' vector (0,1,0).
2428  * \param eye is the position of the viewer's eye.
2429  */
2430 inline void lookAt(Point eye)
2431 {
2432  gluLookAt
2433  (
2434  eye[0], eye[1], eye[2],
2435  0, 0, 0,
2436  0, 1, 0
2437  );
2438 }
2439 
2440 /**
2441  * Call gluLookAt() with 'up' vector (0,1,0).
2442  * \param eye is the position of the viewer's eye in model coordinates.
2443  * \param model is the point at the centre of the view in model coordinates.
2444  */
2445 inline void lookAt(Point eye, Point model)
2446 {
2447  gluLookAt
2448  (
2449  eye[0], eye[1], eye[2],
2450  model[0], model[1], model[2],
2451  0, 1, 0
2452  );
2453 }
2454 
2455 /**
2456  * Call gluLookAt().
2457  * \param eye is the position of the viewer's eye in model coordinates.
2458  * \param model is the point at the centre of the view in model coordinates.
2459  * \param up is a vector giving the upwards direction in the model.
2460  */
2461 inline void lookAt(Point eye, Point model, Vector up)
2462 {
2463  gluLookAt
2464  (
2465  eye[0], eye[1], eye[2],
2466  model[0], model[1], model[2],
2467  up[0], up[1], up[2]
2468  );
2469 }
2470 
2471 // End of free functions
2472 //@}
2473 
2474 
2475 /**
2476  * \defgroup model Materials and Models
2477  */
2478 
2479 //@{
2480 
2481 /**
2482  * \todo Models should probably be put into a separate file.
2483  */
2484 
2485 // Axes
2486 
2487 /**
2488  * Draw coordinate axes.
2489  * This function draws the three principal axes in the current
2490  * position, using \c size to determine the length of each axis.
2491  * The axes are colour-coded: \a X = red, \a Y = green, \a Z = blue.
2492  */
2493 void axes(GLfloat size = 1);
2494 
2495 /**
2496  * Draw an aircraft.
2497  * The argument determines whether the plane is drawn with a metallic
2498  * colour (\c shadow = \c false, the default) or black, to act as a
2499  * shadow (\c shadow = \c true).
2500  * The aircraft is built using Bezier surfaces. If you use glScalef
2501  * to change its size, you must enable \c GL_NORMALIZE to correct
2502  * the normals. Otherwise, the lighting will be wrong.
2503  */
2504 void buildPlane(bool shadow = false);
2505 
2506 /**
2507  * Construct a GL call list for the aircraft and return its index.
2508  */
2509 GLuint makePlaneList(bool shadow = false);
2510 
2511 
2512 /**
2513  * Enumeration for materials.
2514  */
2516 {
2517  BLACK, /**< Black. */
2518  WHITE, /**< White. */
2519  RED, /**< Red. */
2520  GREEN, /**< Green. */
2521  BLUE, /**< Blue. */
2522  METAL, /**< General metallic colour.*/
2523  GLASS, /**< General transparent marterial.*/
2524  BRASS, /**< Brass. */
2525  BRONZE, /**< Matt bronze. */
2526  POLISHED_BRONZE, /**< Polished bronze. */
2527  CHROME, /**< Chrome. */
2528  COPPER, /**< Matt copper. */
2529  POLISHED_COPPER, /**< Polished copper. */
2530  GOLD, /**< Matt gold. */
2531  POLISHED_GOLD, /**< Polished gold. */
2532  PEWTER, /**< Pewter. */
2533  SILVER, /**< Matt silver. */
2534  POLISHED_SILVER, /**< Polished silver. */
2535  EMERALD, /**< Emerald. */
2536  JADE, /**< Jade. */
2537  OBSIDIAN, /**< Obsidian. */
2538  PEARL, /**< Pearl. */
2539  RUBY, /**< Ruby. */
2540  TURQUOISE, /**< Turquoise. */
2541  BLACK_PLASTIC, /**< Black plastic. */
2542  BLACK_RUBBER, /**< Black rubber. */
2543  LAST_VALUE
2544 };
2545 
2546 /**
2547  * Set material values from the enumeration.
2548  \param m is chosen from the enumeration \c MATERIAL
2549  \param face should be one of \c GL_FRONT (the default),
2550  \c GL_BACK, or \c GL_FRONT_AND_BACK.
2551  */
2552 void setMaterial(const int m, GLenum face = GL_FRONT);
2553 
2554 // The following array describes material properties.
2555 // ambiance [4],
2556 // diffuse [4],
2557 // specular [4],
2558 // shininess [1].
2559 // 13 values are required to define a material.
2560 
2561 /**
2562  * Add a material to the set of built-in materials.
2563  * The array of material has a fixed size of 100.
2564  * An attempt to create more than 100 materials will fail.
2565  * The parameters specify:
2566  *
2567  * - RGBA values for ambient light
2568  * - RGBA values for diffuse light
2569  * - RGBA values for specular light
2570  * - Value for shininess exponent
2571  * \return the index of the new material.
2572  */
2574  GLfloat ambR, GLfloat ambG, GLfloat ambB, GLfloat ambA,
2575  GLfloat difR, GLfloat difG, GLfloat difB, GLfloat difA,
2576  GLfloat speR, GLfloat speG, GLfloat speB, GLfloat speA,
2577  GLfloat shine);
2578 
2579 /**
2580  * Add a material to the set of built-in materials.
2581  * The array of material has a fixed size of 100.
2582  * An attempt to create more than 100 materials will fail.
2583  * \param params specifies:
2584  * - RGBA values for ambient light
2585  * - RGBA values for diffuse light
2586  * - RGBA values for specular light
2587  * - Value for shininess exponent
2588  * \return the index of the new material.
2589  */
2590 int addMaterial(GLfloat params[]);
2591 
2592 // End of free functions
2593 //@}
2594 
2595 //=============================== End of declarations ==============================//
2596 
2597 // Code below this point consists of inline function definitions.
2598 // Functions that are not defined here are defined in cugl.cpp.
2599 
2600 // class Point: inlined constructors and member functions.
2601 
2602 inline Point::Point (GLfloat coordinates[])
2603 {
2604  x = coordinates[0];
2605  y = coordinates[1];
2606  z = coordinates[2];
2607  w = coordinates[3];
2608 }
2609 
2610 inline Point Point::operator+=(const Vector & v)
2611 {
2612  x += w * v.x;
2613  y += w * v.y;
2614  z += w * v.z;
2615  return *this;
2616 }
2617 
2618 inline Point Point::operator-=(const Vector & v)
2619 {
2620  x -= w * v.x;
2621  y -= w * v.y;
2622  z -= w * v.z;
2623  return *this;
2624 }
2625 
2626 inline Point Point::operator/(GLfloat s) const
2627 {
2628  return Point(x, y, z, s * w);
2629 }
2630 
2631 inline void Point::draw() const
2632 {
2633  if (w == 0)
2634  return;
2635  glVertex4f(x, y, z, w);
2636 }
2637 
2638 inline void Point::light(GLenum lightNum) const
2639 {
2640  GLfloat p[4];
2641  p[0] = x;
2642  p[1] = y;
2643  p[2] = z;
2644  p[3] = w;
2645  glLightfv(lightNum, GL_POSITION, p);
2646 }
2647 
2648 inline void Point::translate() const
2649 {
2650  glTranslatef(x/w, y/w, z/w);
2651 }
2652 
2653 // class Point: inlined friend functions.
2654 
2655 inline Point operator+(const Point & p, const Vector & v)
2656 {
2657  return Point(p.x + p.w * v.x, p.y + p.w * v.y, p.z + p.w * v.z, p.w);
2658 }
2659 
2660 inline Point operator+(const Vector & v, const Point & p)
2661 {
2662  return Point(p.x + p.w * v.x, p.y + p.w * v.y, p.z + p.w * v.z, p.w);
2663 }
2664 
2665 inline Point operator*(const Point & p, GLfloat s)
2666 {
2667  return Point(s * p.x, s * p.y, s * p.z, s * p.w);
2668 }
2669 
2670 inline Point operator*(GLfloat s, const Point & p)
2671 {
2672  return Point(s * p.x, s * p.y, s * p.z, s * p.w);
2673 }
2674 
2675 inline bool operator==(const Point & p, const Point & q)
2676 {
2677  return p.x == q.x && p.y == q.y && p.z == q.z && p.w == q.w;
2678 }
2679 
2680 inline bool operator!=(const Point & p, const Point & q)
2681 {
2682  return !(p == q);
2683 }
2684 
2685 inline GLfloat dist(const Point & p, const Plane & s)
2686 {
2687  return p.x * s.a + p.y * s.b + p.z * s.c + p.w * s.d;
2688 }
2689 
2690 inline GLfloat dist(const Plane & s, const Point & p)
2691 {
2692  return s.a * p.x + s.b * p.y + s.c * p.z + s.d * p.w;
2693 }
2694 
2695 // Class Line: inlined member functions.
2696 
2697 inline Line::Line(const Point & p, const Point & q)
2698  : s(p), f(q)
2699 { }
2700 
2701 inline Line::Line(const Point & p, const Vector & v)
2702  : s(p), f(p + v)
2703 { }
2704 
2705 
2706 // Class Line: inlined friend functions.
2707 
2708 inline bool operator==(const Line & m, const Line & n)
2709 {
2710  return m.s == n.s && m.f == n.f;
2711 }
2712 
2713 inline bool operator!=(const Line & m, const Line & n)
2714 {
2715  return !(m == n);
2716 }
2717 
2718 
2719 
2720 // Class Plane: inlined member functions.
2721 
2722 inline Vector Plane::normal() const
2723 {
2724  return Vector(a,b,c).unit();
2725 }
2726 
2727 // Class Plane: inlined friend functions.
2728 
2729 inline bool operator==(const Plane & p, const Plane & q)
2730 {
2731  return p.a == q.a && p.b == q.b && p.c == q.c && p.d == q.d;
2732 }
2733 
2734 inline bool operator!=(const Plane & p, const Plane & q)
2735 {
2736  return !(p == q);
2737 }
2738 
2739 
2740 
2741 // class Vector: inlined constructors
2742 
2743 inline Vector::Vector (GLfloat coordinates[])
2744 {
2745  x = coordinates[0];
2746  y = coordinates[1];
2747  z = coordinates[2];
2748 }
2749 
2750 inline Vector::Vector(const Point & p, const Point & q)
2751 {
2752  if (p.w == 0 || q.w == 0)
2753  {
2754  x = 0;
2755  y = 0;
2756  z = 0;
2757  }
2758  else
2759  {
2760  x = p.x/p.w - q.x/q.w;
2761  y = p.y/p.w - q.y/q.w;
2762  z = p.z/p.w - q.z/q.w;
2763  }
2764 }
2765 
2766 inline Vector::Vector(const Quaternion & q)
2767 {
2768  x = q.v.x;
2769  y = q.v.y;
2770  z = q.v.z;
2771 }
2772 
2773 // class Vector: inlined member functions.
2774 
2776 {
2777  x += v.x;
2778  y += v.y;
2779  z += v.z;
2780  return *this;
2781 }
2782 
2784 {
2785  x -= v.x;
2786  y -= v.y;
2787  z -= v.z;
2788  return *this;
2789 }
2790 
2792 {
2793  return Vector(-x, -y, -z);
2794 }
2795 
2796 inline Vector Vector::operator*=(GLfloat scale)
2797 {
2798  x *= scale;
2799  y *= scale;
2800  z *= scale;
2801  return *this;
2802 }
2803 
2804 inline GLfloat Vector::norm() const
2805 {
2806  return x * x + y * y + z * z;
2807 }
2808 
2809 inline GLfloat Vector::length() const
2810 {
2811  return GLfloat(sqrt(norm()));
2812 }
2813 
2814 inline void Vector::translate() const
2815 {
2816  glTranslatef(x, y, z);
2817 }
2818 
2820 {
2821  return Matrix(
2822  0.0f, z, -y, 0.0f,
2823  -z, 0.0f, x, 0.0f,
2824  y, -x, -0.0f, 0.0f,
2825  0.0f, 0.0f, 0.0f, 1.0f );
2826 }
2827 
2828 inline void Vector::drawNormal() const
2829 {
2830  glNormal3f(x, y, z);
2831 }
2832 
2833 inline void Vector::draw(const Point & p) const
2834 {
2835  glBegin(GL_LINES);
2836  p.draw();
2837  (p + (*this)).draw();
2838  glEnd();
2839 }
2840 
2841 // class Vector: inlined friend functions.
2842 
2843 inline Vector operator-(const Point & p, const Point & q)
2844 {
2845  if (p.w == 0 || q.w == 0)
2846  return Vector();
2847  else
2848  return Vector(p.x/p.w - q.x/q.w, p.y/p.w - q.y/q.w, p.z/p.w - q.z/q.w);
2849 }
2850 
2851 inline Vector operator+(const Vector & u, const Vector & v)
2852 {
2853  return Vector(u.x + v.x, u.y + v.y, u.z + v.z);
2854 }
2855 
2856 inline Vector operator-(const Vector & u, const Vector & v)
2857 {
2858  return Vector(u.x - v.x, u.y - v.y, u.z - v.z);
2859 }
2860 
2861 inline Vector operator*(const Vector & v, GLfloat s)
2862 {
2863  return Vector(s * v.x, s * v.y, s * v.z);
2864 }
2865 
2866 inline Vector operator*(GLfloat s, const Vector & v)
2867 {
2868  return Vector(s * v.x, s * v.y, s * v.z);
2869 }
2870 
2871 inline Vector cross(const Vector & u, const Vector & v)
2872 {
2873  return Vector(
2874  u.y * v.z - u.z * v.y,
2875  u.z * v.x - u.x * v.z,
2876  u.x * v.y - u.y * v.x );
2877 }
2878 
2879 inline Vector operator*(const Vector & u, const Vector & v)
2880 {
2881  return Vector(
2882  u.y * v.z - u.z * v.y,
2883  u.z * v.x - u.x * v.z,
2884  u.x * v.y - u.y * v.x );
2885 }
2886 
2887 inline GLfloat dot(const Vector & u, const Vector & v)
2888 {
2889  return u.x * v.x + u.y * v.y + u.z * v.z;
2890 }
2891 
2892 inline bool operator==(const Vector & u, const Vector & v)
2893 {
2894  return u.x == v.x && u.y == v.y && u.z == v.z;
2895 }
2896 
2897 inline bool operator!=(const Vector & u, const Vector & v)
2898 {
2899  return !(u == v);
2900 }
2901 
2902 
2903 
2904 // Class Matrix: inlined constructors
2905 
2906 inline Matrix::Matrix(const Plane & p)
2907 {
2908  reflect(p);
2909 }
2910 
2911 inline Matrix::Matrix(const Point & lightPos, const Plane & plane)
2912 {
2913  shadow(lightPos, plane);
2914 }
2915 
2917  GLfloat m00, GLfloat m10, GLfloat m20, GLfloat m30,
2918  GLfloat m01, GLfloat m11, GLfloat m21, GLfloat m31,
2919  GLfloat m02, GLfloat m12, GLfloat m22, GLfloat m32,
2920  GLfloat m03, GLfloat m13, GLfloat m23, GLfloat m33 )
2921 {
2922  m[0][0] = m00;
2923  m[1][0] = m10;
2924  m[2][0] = m20;
2925  m[3][0] = m30;
2926  m[0][1] = m01;
2927  m[1][1] = m11;
2928  m[2][1] = m21;
2929  m[3][1] = m31;
2930  m[0][2] = m02;
2931  m[1][2] = m12;
2932  m[2][2] = m22;
2933  m[3][2] = m32;
2934  m[0][3] = m03;
2935  m[1][3] = m13;
2936  m[2][3] = m23;
2937  m[3][3] = m33;
2938 }
2939 
2940 // Class Matrix: inlined member functions
2941 
2942 inline Point Matrix::apply(const Point & p) const
2943 {
2944  return Point
2945  (
2946  m[0][0] * p.x + m[0][1] * p.y + m[0][2] * p.z + m[0][3] * p.w,
2947  m[1][0] * p.x + m[1][1] * p.y + m[1][2] * p.z + m[1][3] * p.w,
2948  m[2][0] * p.x + m[2][1] * p.y + m[2][2] * p.z + m[2][3] * p.w,
2949  m[3][0] * p.x + m[3][1] * p.y + m[3][2] * p.z + m[3][3] * p.w
2950  );
2951 }
2952 
2953 inline void Matrix::apply() const
2954 {
2955  glMultMatrixf(&m[0][0]);
2956 }
2957 
2958 inline GLfloat *Matrix::get()
2959 {
2960  return &m[0][0];
2961 }
2962 
2963 inline GLfloat & Matrix::operator()(int i, int j)
2964 {
2965  return m[i][j];
2966 }
2967 
2968 inline const GLfloat & Matrix::operator()(int i, int j) const
2969 {
2970  return m[i][j];
2971 }
2972 
2974 {
2975  return inv();
2976 }
2977 
2978 inline Vector Matrix::apply(const Vector & v) const
2979 {
2980  // Gives same result as quaternion.
2981  return Vector
2982  (
2983  m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
2984  m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
2985  m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]
2986  );
2987 }
2988 
2989 inline Matrix & Matrix::operator/=(GLfloat s)
2990 {
2991  m[0][0] /= s;
2992  m[0][1] /= s;
2993  m[0][2] /= s;
2994  m[0][3] /= s;
2995  m[1][0] /= s;
2996  m[1][1] /= s;
2997  m[1][2] /= s;
2998  m[1][3] /= s;
2999  m[2][0] /= s;
3000  m[2][1] /= s;
3001  m[2][2] /= s;
3002  m[2][3] /= s;
3003  m[3][0] /= s;
3004  m[3][1] /= s;
3005  m[3][2] /= s;
3006  m[3][3] /= s;
3007  return *this;
3008 }
3009 
3010 inline Matrix & Matrix::operator*=(GLfloat s)
3011 {
3012  m[0][0] *= s;
3013  m[0][1] *= s;
3014  m[0][2] *= s;
3015  m[0][3] *= s;
3016  m[1][0] *= s;
3017  m[1][1] *= s;
3018  m[1][2] *= s;
3019  m[1][3] *= s;
3020  m[2][0] *= s;
3021  m[2][1] *= s;
3022  m[2][2] *= s;
3023  m[2][3] *= s;
3024  m[3][0] *= s;
3025  m[3][1] *= s;
3026  m[3][2] *= s;
3027  m[3][3] *= s;
3028  return *this;
3029 }
3030 
3031 // Class Matrix: inlined friend functions
3032 
3033 inline Matrix Matrix::operator+=(const Matrix & rhs)
3034 {
3035  for (int c = 0; c < 4; ++c)
3036  for (int r = 0; r < 4; ++r)
3037  m[c][r] += rhs(c,r);
3038  return *this;
3039 }
3040 
3041 inline Matrix operator+(const Matrix & m, const Matrix & n)
3042 {
3043  Matrix sum(m);
3044  sum += n;
3045  return sum;
3046 }
3047 
3048 inline Matrix Matrix::operator-=(const Matrix & rhs)
3049 {
3050  for (int c = 0; c < 4; ++c)
3051  for (int r = 0; r < 4; ++r)
3052  m[c][r] -= rhs(c,r);
3053  return *this;
3054 }
3055 
3056 inline Matrix operator-(const Matrix & m, const Matrix & n)
3057 {
3058  Matrix sum(m);
3059  sum -= n;
3060  return sum;
3061 }
3062 
3063 inline Matrix Matrix::operator*=(const Matrix & rhs)
3064 {
3065  *this = (*this) * rhs;
3066  return *this;
3067 }
3068 
3069 inline Matrix operator*(const Matrix & m, const Matrix & n)
3070 {
3071  Matrix r;
3072  r(0,0) = m(0,0) * n(0,0) + m(0,1) * n(1,0) + m(0,2) * n(2,0) + m(0,3) * n(3,0);
3073  r(0,1) = m(0,0) * n(0,1) + m(0,1) * n(1,1) + m(0,2) * n(2,1) + m(0,3) * n(3,1);
3074  r(0,2) = m(0,0) * n(0,2) + m(0,1) * n(1,2) + m(0,2) * n(2,2) + m(0,3) * n(3,2);
3075  r(0,3) = m(0,0) * n(0,3) + m(0,1) * n(1,3) + m(0,2) * n(2,3) + m(0,3) * n(3,3);
3076  r(1,0) = m(1,0) * n(0,0) + m(1,1) * n(1,0) + m(1,2) * n(2,0) + m(1,3) * n(3,0);
3077  r(1,1) = m(1,0) * n(0,1) + m(1,1) * n(1,1) + m(1,2) * n(2,1) + m(1,3) * n(3,1);
3078  r(1,2) = m(1,0) * n(0,2) + m(1,1) * n(1,2) + m(1,2) * n(2,2) + m(1,3) * n(3,2);
3079  r(1,3) = m(1,0) * n(0,3) + m(1,1) * n(1,3) + m(1,2) * n(2,3) + m(1,3) * n(3,3);
3080  r(2,0) = m(2,0) * n(0,0) + m(2,1) * n(1,0) + m(2,2) * n(2,0) + m(2,3) * n(3,0);
3081  r(2,1) = m(2,0) * n(0,1) + m(2,1) * n(1,1) + m(2,2) * n(2,1) + m(2,3) * n(3,1);
3082  r(2,2) = m(2,0) * n(0,2) + m(2,1) * n(1,2) + m(2,2) * n(2,2) + m(2,3) * n(3,2);
3083  r(2,3) = m(2,0) * n(0,3) + m(2,1) * n(1,3) + m(2,2) * n(2,3) + m(2,3) * n(3,3);
3084  r(3,0) = m(3,0) * n(0,0) + m(3,1) * n(1,0) + m(3,2) * n(2,0) + m(3,3) * n(3,0);
3085  r(3,1) = m(3,0) * n(0,1) + m(3,1) * n(1,1) + m(3,2) * n(2,1) + m(3,3) * n(3,1);
3086  r(3,2) = m(3,0) * n(0,2) + m(3,1) * n(1,2) + m(3,2) * n(2,2) + m(3,3) * n(3,2);
3087  r(3,3) = m(3,0) * n(0,3) + m(3,1) * n(1,3) + m(3,2) * n(2,3) + m(3,3) * n(3,3);
3088  return r;
3089 }
3090 
3091 inline bool operator==(const Matrix & m, const Matrix & n)
3092 {
3093  for (int i = 0; i < 4; i++)
3094  for (int j = 0; j < 4; j++)
3095  if (m(i,j) != n(i,j))
3096  return false;
3097  return true;
3098 }
3099 
3100 inline bool operator!=(const Matrix & m, const Matrix & n)
3101 {
3102  for (int i = 0; i < 4; i++)
3103  for (int j = 0; j < 4; j++)
3104  if (m(i,j) != n(i,j))
3105  return true;
3106  return false;
3107 }
3108 
3109 inline Matrix operator*(GLfloat s, const Matrix & m)
3110 {
3111  Matrix sm;
3112  for (int i = 0; i < 4; i++)
3113  for (int j = 0; j < 4; j++)
3114  sm(i, j) = s * m(i, j);
3115  return sm;
3116 }
3117 
3118 inline Matrix operator*(const Matrix & m, GLfloat s)
3119 {
3120  Matrix ms;
3121  for (int i = 0; i < 4; i++)
3122  for (int j = 0; j < 4; j++)
3123  ms(i, j) = s * m(i, j);
3124  return ms;
3125 }
3126 
3127 inline Matrix operator/(const Matrix & m, GLfloat s)
3128 {
3129  Matrix md = m;
3130  return md /= s;
3131 }
3132 
3133 
3134 // Class Quaternion: inlined member functions.
3135 
3137 {
3138  s += q.s;
3139  v += q.v;
3140  return *this;
3141 }
3142 
3144 {
3145  s -= q.s;
3146  v -= q.v;
3147  return *this;
3148 }
3149 
3151 {
3152  v *= x;
3153  s *= x;
3154  return *this;
3155 }
3156 
3158 {
3159  v /= x;
3160  s /= x;
3161  return *this;
3162 }
3163 
3164 inline Vector Quaternion::apply(const Vector & w) const
3165 {
3166  return Vector
3167  (
3168  -(-w[0] * v[0] - w[1] * v[1] - w[2] * v[2]) * v[0] + s * (s * w[0] + w[1] * v[2] - w[2] * v[1])
3169  - v[1] * (s * w[2] + w[0] * v[1] - w[1] * v[0]) + v[2] * (s * w[1] + w[2] * v[0] - w[0] * v[2]),
3170  -(-w[0] * v[0] - w[1] * v[1] - w[2] * v[2]) * v[1] + s * (s * w[1] + w[2] * v[0] - w[0] * v[2])
3171  - v[2] * (s * w[0] + w[1] * v[2] - w[2] * v[1]) + v[0] * (s * w[2] + w[0] * v[1] - w[1] * v[0]),
3172  -(-w[0] * v[0] - w[1] * v[1] - w[2] * v[2]) * v[2] + s * (s * w[2] + w[0] * v[1] - w[1] * v[0])
3173  - v[0] * (s * w[1] + w[2] * v[0] - w[0] * v[2]) + v[1] * (s * w[0] + w[1] * v[2] - w[2] * v[1])
3174  );
3175 }
3176 
3178 {
3179  return v;
3180 }
3181 
3182 inline GLfloat Quaternion::scalar() const
3183 {
3184  return s;
3185 }
3186 
3187 inline GLfloat Quaternion::norm() const
3188 {
3189  return s * s + v.norm();
3190 }
3191 
3192 inline GLfloat Quaternion::magnitude() const
3193 {
3194  return GLfloat(sqrt(norm()));
3195 }
3196 
3198 {
3199  return Quaternion(s, -v);
3200 }
3201 
3202 inline Vector Quaternion::axis() const
3203 {
3204  return v.unit();
3205 }
3206 
3207 inline double Quaternion::angle() const
3208 {
3209  return 2 * acos(s);
3210 }
3211 
3213 {
3214  return inv();
3215 }
3216 
3218 {
3219  GLfloat ns = s * q.s - v[0] * q.v[0] - v[1] * q.v[1] - v[2] * q.v[2];
3220  v = Vector(
3221  q.s * v[0] + s * q.v[0] + v[1] * q.v[2] - v[2] * q.v[1],
3222  q.s * v[1] + s * q.v[1] + v[2] * q.v[0] - v[0] * q.v[2],
3223  q.s * v[2] + s * q.v[2] + v[0] * q.v[1] - v[1] * q.v[0] );
3224  s = ns;
3225  return *this;
3226 
3227 }
3228 
3229 // class Quaternion: inlined friend functions.
3230 
3231 inline GLfloat dot(const Quaternion & q, const Quaternion & r)
3232 {
3233  return q.s * r.s + dot(q.v, r.v);
3234 }
3235 
3236 inline Quaternion operator+(const Quaternion & q, const Quaternion & r)
3237 {
3238  return Quaternion(q.s + r.s, q.v + r.v);
3239 }
3240 
3241 inline Quaternion operator-(const Quaternion & q, const Quaternion & r)
3242 {
3243  return Quaternion(q.s - r.s, q.v - r.v);
3244 }
3245 
3246 inline Quaternion operator*(const Quaternion & q, const Quaternion & r)
3247 {
3248  return Quaternion
3249  (
3250  q.s * r.s - q.v[0] * r.v[0] - q.v[1] * r.v[1] - q.v[2] * r.v[2],
3251  r.s * q.v[0] + q.s * r.v[0] + q.v[1] * r.v[2] - q.v[2] * r.v[1],
3252  r.s * q.v[1] + q.s * r.v[1] + q.v[2] * r.v[0] - q.v[0] * r.v[2],
3253  r.s * q.v[2] + q.s * r.v[2] + q.v[0] * r.v[1] - q.v[1] * r.v[0]
3254  );
3255 }
3256 
3257 inline Quaternion operator*(const Vector & v, const Quaternion & q)
3258 {
3259  return Quaternion
3260  (
3261  - v[0] * q.v[0] - v[1] * q.v[1] - v[2] * q.v[2],
3262  q.s * v[0] + v[1] * q.v[2] - v[2] * q.v[1],
3263  q.s * v[1] + v[2] * q.v[0] - v[0] * q.v[2],
3264  q.s * v[2] + v[0] * q.v[1] - v[1] * q.v[0]
3265  );
3266 }
3267 
3268 inline Quaternion operator*(const Quaternion & q, const Vector & v)
3269 {
3270  return Quaternion
3271  (
3272  - q.v[0] * v[0] - q.v[1] * v[1] - q.v[2] * v[2],
3273  q.s * v[0] + q.v[1] * v[2] - q.v[2] * v[1],
3274  q.s * v[1] + q.v[2] * v[0] - q.v[0] * v[2],
3275  q.s * v[2] + q.v[0] * v[1] - q.v[1] * v[0]
3276  );
3277 }
3278 
3280 {
3281  GLfloat den = q.norm();
3282  GLfloat ns = (s * q.s + v[0] * q.v[0] + v[1] * q.v[1] + v[2] * q.v[2]) / den;
3283  v = Vector
3284  (
3285  (q.s * v[0] - s * q.v[0] - v[1] * q.v[2] + v[2] * q.v[1]) / den,
3286  (q.s * v[1] - s * q.v[1] - v[2] * q.v[0] + v[0] * q.v[2]) / den,
3287  (q.s * v[2] - s * q.v[2] - v[0] * q.v[1] + v[1] * q.v[0]) / den
3288  );
3289  s = ns;
3290  return *this;
3291 }
3292 
3293 inline Quaternion operator*(const Quaternion & q, GLfloat a)
3294 {
3295  return Quaternion(a * q.s, a * q.v);
3296 }
3297 
3298 inline Quaternion operator*(GLfloat a, const Quaternion & q)
3299 {
3300  return Quaternion(a * q.s, a * q.v);
3301 }
3302 
3303 inline bool operator==(const Quaternion & q, const Quaternion & r)
3304 {
3305  return q.s == r.s && q.v == r.v;
3306 }
3307 
3308 inline bool operator!=(const Quaternion & q, const Quaternion & r)
3309 {
3310  return !(q == r);
3311 }
3312 
3313 
3314 
3315 
3316 
3317 // class Interpolator: inline member functions
3318 
3319 inline void Interpolator::getMatrix(double t, GL_Matrix m) const
3320 {
3321  getQuaternion(t).matrix(m);
3322 }
3323 
3324 }
3325 ; // end of namespace
3326 
3327 #endif
3328 
3329 
void setSteps(int s)
Definition: cugl.h:1616
virtual void apply() const =0
virtual void update()
Definition: cugl.h:1643
virtual void idle()=0
Point eyeNew
Definition: cugl.h:1818
void moveUp(GLfloat distance)
void update(const Point &e, const Point &m)
void set(const Point &eye, const Point &model)
Point model
Definition: cugl.h:1822
void moveForward(GLfloat distance)
Point eye
Definition: cugl.h:1812
void set(const Point &eye)
Camera(const Point &eye, const Point &model, const Vector &up)
void set(const Point &eye, const Point &model, const Vector &up)
void setMode(bool mode)
Definition: cugl.h:1791
bool smooth
Definition: cugl.h:1834
Camera(const Point &eye)
Point modelNew
Definition: cugl.h:1828
Point eyeOld
Definition: cugl.h:1815
void apply() const
void moveLeft(GLfloat distance)
Vector up
Definition: cugl.h:1831
virtual void idle()
void tiltUp(double angle)
friend std::ostream & operator<<(std::ostream &os, const Camera &c)
Point modelOld
Definition: cugl.h:1825
void panLeft(double angle)
Camera(const Point &eye, const Point &model)
virtual void idle()
double cosOmega
Definition: cugl.h:1943
void getMatrix(double t, GL_Matrix m) const
Definition: cugl.h:3319
void apply(double t) const
Quaternion current
Definition: cugl.h:1928
void set(const Quaternion &qFirst, const Quaternion &qLast)
double sinOmega
Definition: cugl.h:1940
Quaternion last
Definition: cugl.h:1934
Quaternion getQuaternion(double t) const
Interpolator(const Quaternion &qFirst, const Quaternion &qLast)
double omega
Definition: cugl.h:1937
virtual void update()
Definition: cugl.h:1917
Quaternion first
Definition: cugl.h:1931
virtual void apply() const
Point f
Definition: cugl.h:450
friend bool operator!=(const Line &x, const Line &y)
Definition: cugl.h:2713
Line(const Point &p, const Point &q)
Definition: cugl.h:2697
Point s
Definition: cugl.h:447
void draw() const
friend Point meet(const Line &k, const Plane &p)
friend bool operator==(const Line &x, const Line &y)
Definition: cugl.h:2708
friend std::ostream & operator<<(std::ostream &os, const Line &k)
friend std::ostream & operator<<(std::ostream &os, const Matrix &m)
Matrix & operator/=(GLfloat s)
Definition: cugl.h:2989
void shadow(const Point &lightPos, const Plane &plane)
GLfloat trace()
Definition: cugl.h:986
Quaternion quaternion() const
GLfloat & operator()(int i, int j)
Definition: cugl.h:2963
friend Matrix operator-(const Matrix &m, const Matrix &n)
Definition: cugl.h:3056
Matrix(const Vector &axis, double theta)
Matrix(const Quaternion &q)
friend bool operator==(const Matrix &x, const Matrix &y)
Definition: cugl.h:3091
Matrix operator-=(const Matrix &rhs)
Definition: cugl.h:3048
GLfloat * get()
Definition: cugl.h:2958
Matrix operator+=(const Matrix &rhs)
Definition: cugl.h:3033
Matrix(const Vector &u, const Vector &v)
void reflect(const Plane &p)
Matrix operator~() const
Definition: cugl.h:2973
friend Matrix operator+(const Matrix &m, const Matrix &n)
Definition: cugl.h:3041
friend Matrix operator*(const Matrix &m, const Matrix &n)
Definition: cugl.h:3069
Matrix inv() const
friend Matrix operator/(const Matrix &m, GLfloat s)
Definition: cugl.h:3127
double angle() const
Matrix operator*=(const Matrix &rhs)
Definition: cugl.h:3063
Matrix(GL_Matrix r)
friend bool operator!=(const Matrix &x, const Matrix &y)
Definition: cugl.h:3100
GL_Matrix m
Definition: cugl.h:1133
Matrix transpose() const
Vector axis() const
void apply() const
Definition: cugl.h:2953
Matrix(GLenum mode)
void read(GLint x, GLint y, GLsizei w, GLsizei h, GLenum mode=GL_FRONT)
void read(const char *bmpFileName)
bool ready() const
Definition: cugl.h:2149
void setTexture(GLuint name)
unsigned long size
Definition: cugl.h:2177
bool allocate(unsigned long newSize)
unsigned long getColumns() const
Definition: cugl.h:2125
unsigned long numRows
Definition: cugl.h:2171
PixelMap(const PixelMap &pm)
friend std::ostream & operator<<(std::ostream &os, const PixelMap &pm)
unsigned long getSize() const
Definition: cugl.h:2133
PixelMap(GLint x, GLint y, GLsizei w, GLsizei h)
void write(const char *bmpFileName)
friend void mix(const PixelMap &m1, const PixelMap &m2, PixelMap &res, double prop)
friend bool compatible(const PixelMap &m1, const PixelMap &m2)
unsigned long numCols
Definition: cugl.h:2174
void select(const PixelMap &src, int xp, int yp, int width, int height)
char * getName() const
Definition: cugl.h:2141
PixelMap(const char *bmpFileName)
unsigned long getRows() const
Definition: cugl.h:2117
unsigned char * pixels
Definition: cugl.h:2183
char * fileName
Definition: cugl.h:2180
void setMipmaps(GLuint name)
GLfloat c
Definition: cugl.h:598
Plane(GLfloat a=0, GLfloat b=1, GLfloat c=0, GLfloat d=0)
friend bool operator!=(const Plane &x, const Plane &y)
Definition: cugl.h:2734
Plane unit() const
Plane(const Vector &v, const Point &p)
GLfloat a
Definition: cugl.h:592
GLfloat getB()
Definition: cugl.h:581
Vector normal() const
Definition: cugl.h:2722
GLfloat b
Definition: cugl.h:595
friend GLfloat dist(const Point &p, const Plane &s)
Definition: cugl.h:2685
Plane(const Line &s, const Point &p)
void clipPlane(GLenum index) const
GLfloat getD()
Definition: cugl.h:587
void normalize()
GLfloat getA()
Definition: cugl.h:578
friend Point meet(const Line &k, const Plane &p)
GLfloat getC()
Definition: cugl.h:584
GLfloat d
Definition: cugl.h:601
Plane(const Point &p, const Point &q, const Point &r)
friend std::ostream & operator<<(std::ostream &os, const Plane &p)
friend bool operator==(const Plane &x, const Plane &y)
Definition: cugl.h:2729
void translate() const
Definition: cugl.h:2648
Point operator+=(const Vector &v)
Definition: cugl.h:2610
Point(const Quaternion &q)
void draw() const
Definition: cugl.h:2631
GLfloat z
Definition: cugl.h:380
Point operator-=(const Vector &v)
Definition: cugl.h:2618
friend bool operator!=(const Point &p, const Point &q)
Definition: cugl.h:2680
GLfloat & operator[](int i)
Point unit() const
friend GLfloat dist(const Point &p, const Plane &s)
Definition: cugl.h:2685
void normalize()
friend Vector operator-(const Point &p, const Point &q)
Definition: cugl.h:2843
friend Point operator+(const Vector &v, const Point &p)
Definition: cugl.h:2660
Point operator/(GLfloat s) const
Definition: cugl.h:2626
friend double dist(const Point &p, const Point &q)
Definition: cugl.h:366
GLfloat x
Definition: cugl.h:374
friend std::ostream & operator<<(std::ostream &os, const Point &p)
friend Point operator*(const Point &p, GLfloat s)
Definition: cugl.h:2665
friend Point meet(const Line &k, const Plane &p)
Point(GLfloat x=0, GLfloat y=0, GLfloat z=0, GLfloat w=1)
const GLfloat & operator[](int i) const
friend bool operator==(const Point &p, const Point &q)
Definition: cugl.h:2675
GLfloat w
Definition: cugl.h:383
void light(GLenum lightNum) const
Definition: cugl.h:2638
GLfloat y
Definition: cugl.h:377
GLfloat norm() const
Definition: cugl.h:3187
Quaternion & operator/=(const Quaternion &q)
Definition: cugl.h:3279
GLfloat s
Definition: cugl.h:1555
void apply() const
Quaternion(Vector axis, double angle)
Definition: cugl.h:1191
Vector vector() const
Definition: cugl.h:3177
Quaternion unit() const
Quaternion operator+=(const Quaternion &q)
Definition: cugl.h:3136
Vector v
Definition: cugl.h:1558
friend Quaternion log(const Quaternion &q)
Definition: cugl.h:1470
friend Quaternion exp(const Vector &v)
Definition: cugl.h:1495
void trackball(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
Quaternion(double xr, double yr, double zr)
friend Quaternion exp(const Quaternion &q)
Definition: cugl.h:1482
Quaternion(const Point &p)
Quaternion(Matrix m)
friend GLfloat dot(const Quaternion &q, const Quaternion &r)
Definition: cugl.h:3231
Quaternion(const Vector &v)
Definition: cugl.h:1172
friend Quaternion operator*(const Quaternion &q, const Quaternion &r)
Definition: cugl.h:3246
Quaternion operator/(GLfloat scale) const
void euler(double &xr, double &yr, double &zr) const
Quaternion conj() const
Definition: cugl.h:3197
friend Quaternion operator+(const Quaternion &q, const Quaternion &r)
Definition: cugl.h:3236
friend std::ostream & operator<<(std::ostream &os, const Quaternion &q)
GLfloat magnitude() const
Definition: cugl.h:3192
Quaternion(const Vector &u, const Vector &v)
GLfloat scalar() const
Definition: cugl.h:3182
void matrix(Matrix &m) const
void integrate(const Vector &omega, double dt)
Quaternion inv() const
Quaternion(GLfloat s, const Vector &v)
Definition: cugl.h:1181
Vector axis() const
Definition: cugl.h:3202
friend bool operator==(const Quaternion &x, const Quaternion &y)
Definition: cugl.h:3303
friend Quaternion operator-(const Quaternion &q, const Quaternion &r)
Definition: cugl.h:3241
double angle() const
Definition: cugl.h:3207
friend bool operator!=(const Quaternion &x, const Quaternion &y)
Definition: cugl.h:3308
Quaternion(GLfloat s, GLfloat x, GLfloat y, GLfloat z)
Definition: cugl.h:1162
Quaternion & operator*=(const Quaternion &q)
Definition: cugl.h:3217
void matrix(GL_Matrix m) const
Quaternion operator~() const
Definition: cugl.h:3212
Quaternion operator-=(const Quaternion &q)
Definition: cugl.h:3143
void setSlices(int slices)
Revolute(int numSteps, GLfloat profile[][2])
Revolute(const Revolute &)
const Revolute & operator=(const Revolute &)
void draw(bool showNormals=false)
void setEccentricity(double ecc)
GLfloat y
Definition: cugl.h:851
Vector(GLfloat x, GLfloat y, GLfloat z)
Definition: cugl.h:628
Vector operator/(GLfloat scale) const
GLfloat norm() const
Definition: cugl.h:2804
Vector operator/=(GLfloat scale)
friend bool operator==(const Vector &x, const Vector &y)
Definition: cugl.h:2892
Vector(Point points[], int numPoints)
Vector operator-=(const Vector &v)
Definition: cugl.h:2783
Matrix skew()
Definition: cugl.h:2819
GLfloat & operator[](int i)
friend Vector operator*(const Vector &u, const Vector &v)
Definition: cugl.h:2879
void drawNormal() const
Definition: cugl.h:2828
Vector unit() const
void translate() const
Definition: cugl.h:2814
Vector operator+=(const Vector &v)
Definition: cugl.h:2775
GLfloat length() const
Definition: cugl.h:2809
Vector operator*=(GLfloat scale)
Definition: cugl.h:2796
friend Vector operator+(const Vector &u, const Vector &v)
Definition: cugl.h:2851
GLfloat x
Definition: cugl.h:848
friend std::ostream & operator<<(std::ostream &os, const Vector &v)
void normalize()
const GLfloat & operator[](int i) const
void draw(const Point &p=Point()) const
Definition: cugl.h:2833
friend bool operator!=(const Vector &x, const Vector &y)
Definition: cugl.h:2897
GLfloat z
Definition: cugl.h:854
friend GLfloat dot(const Vector &u, const Vector &v)
Definition: cugl.h:2887
Vector()
Definition: cugl.h:622
friend Vector cross(const Vector &u, const Vector &v)
Definition: cugl.h:2871
Vector operator-() const
Definition: cugl.h:2791
Definition: cugl.h:56
GLfloat GL_Matrix[4][4]
Definition: cugl.h:74
const Vector I(1, 0, 0)
Vector cross(const Vector &u, const Vector &v)
Definition: cugl.h:2871
void checkOpenGLStatus()
const Vector K(0, 0, 1)
Point operator*(const Point &p, GLfloat s)
Definition: cugl.h:2665
Matrix operator/(const Matrix &m, GLfloat s)
Definition: cugl.h:3127
void lookAt(Point eye)
Definition: cugl.h:2430
double degrees(double angle)
Definition: cugl.h:2335
void triStripNormals(Point points[], Vector normals[], int numPoints, bool neg=false)
bool operator==(const Point &p, const Point &q)
Definition: cugl.h:2675
void revolve(int numSteps, GLfloat coor[][2], int numSlices, bool drawNormals=false)
void setMaterial(const int m, GLenum face=GL_FRONT)
Point operator+(const Point &p, const Vector &v)
Definition: cugl.h:2655
double radians(double angle)
Definition: cugl.h:2327
void buildPlane(bool shadow=false)
MATERIAL
Definition: cugl.h:2516
@ RED
Definition: cugl.h:2519
@ COPPER
Definition: cugl.h:2528
@ SILVER
Definition: cugl.h:2533
@ TURQUOISE
Definition: cugl.h:2540
@ GREEN
Definition: cugl.h:2520
@ POLISHED_GOLD
Definition: cugl.h:2531
@ BLACK_PLASTIC
Definition: cugl.h:2541
@ BLACK
Definition: cugl.h:2517
@ OBSIDIAN
Definition: cugl.h:2537
@ POLISHED_BRONZE
Definition: cugl.h:2526
@ POLISHED_SILVER
Definition: cugl.h:2534
@ POLISHED_COPPER
Definition: cugl.h:2529
@ BRONZE
Definition: cugl.h:2525
@ BRASS
Definition: cugl.h:2524
@ PEWTER
Definition: cugl.h:2532
@ BLACK_RUBBER
Definition: cugl.h:2542
@ GOLD
Definition: cugl.h:2530
@ PEARL
Definition: cugl.h:2538
@ CHROME
Definition: cugl.h:2527
@ RUBY
Definition: cugl.h:2539
@ WHITE
Definition: cugl.h:2518
@ METAL
Definition: cugl.h:2522
@ JADE
Definition: cugl.h:2536
@ GLASS
Definition: cugl.h:2523
@ BLUE
Definition: cugl.h:2521
@ EMERALD
Definition: cugl.h:2535
double sqr(double x)
Definition: cugl.h:2341
int addMaterial(GLfloat ambR, GLfloat ambG, GLfloat ambB, GLfloat ambA, GLfloat difR, GLfloat difG, GLfloat difB, GLfloat difA, GLfloat speR, GLfloat speG, GLfloat speB, GLfloat speA, GLfloat shine)
const char * getErrorString(CUGLErrorType err)
bool operator!=(const Point &p, const Point &q)
Definition: cugl.h:2680
void checkCUGLStatus()
const Vector J(0, 1, 0)
void axes(GLfloat size=1)
GLfloat dot(const Vector &u, const Vector &v)
Definition: cugl.h:2887
const char version[]
Definition: cugl.h:63
int randSym(unsigned int max)
Definition: cugl.h:2362
CUGLErrorType
Definition: cugl.h:82
@ OPEN_FAILED
Definition: cugl.h:91
@ NOT_ENOUGH_MEMORY
Definition: cugl.h:95
@ TOO_MANY_MATERIALS
Definition: cugl.h:99
@ ZERO_DIVISOR
Definition: cugl.h:88
@ TOO_MANY_POINTS
Definition: cugl.h:100
@ NOT_24_BITS
Definition: cugl.h:93
@ ZERO_NORM
Definition: cugl.h:89
@ NOT_BMP_FILE
Definition: cugl.h:92
@ NO_PIX_MAP
Definition: cugl.h:96
@ BAD_ROTATION_MATRIX
Definition: cugl.h:86
@ BAD_INDEX
Definition: cugl.h:84
@ BAD_MATRIX_MODE
Definition: cugl.h:85
@ COMPRESSED_BMP_FILE
Definition: cugl.h:94
@ BAD_LINE
Definition: cugl.h:98
@ NO_ERROR
Definition: cugl.h:83
@ BAD_PLANE
Definition: cugl.h:97
@ BAD_INTERPOLATOR_ARG
Definition: cugl.h:90
@ SINGULAR_MATRIX
Definition: cugl.h:87
const double PI
Definition: cugl.h:66
double randReal()
Definition: cugl.h:2368
GLfloat * GLfloatArray
Definition: cugl.h:2188
unsigned int randInt(unsigned int max)
Definition: cugl.h:2347
GLfloat dist(const Point &p, const Plane &s)
Definition: cugl.h:2685
GLuint makePlaneList(bool shadow=false)
CUGLErrorType getError()
Vector operator-(const Point &p, const Point &q)
Definition: cugl.h:2843