/***************************************************************************
                           matrix3d.h
                           -------------------
    copyright            : (C) 2004 by Jos van den Oever
    email                : jos@vandenoever.info
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#ifndef MATRIX3D_H
#define MATRIX3D_H

/* A matrix class that allows the mapping of a set of coordinates in 3D to
   coordinates in a rotated and scaled 3D space.
   The rotation is determined by four parameters. The first two (t and p)
   parameters define a point on a circle in spherical coordinates.
      x = sin(t)*cos(p)
      y = sin(t)*sin(p)
      z = cos(t)
   The range for t is 0 <= t <= pi. The range for p is 0 <= p <= 2*pi.
   The parameter r gives the rotation around the vector given by t and p.

   The real matrix is calculated from t, p and r by calculating the elemenary
   vectors (1,0,0), (0,1,0), (0,0,1) for the rotated space. These three
   vectors next to each other form the matrix.

   The matrix can be rotated from the point of view of the rotated space with
   the functions rotX, rotY and rotZ. These functions update the matrix directly.
   The parameters t, p and r are inferred from the matrix by calling the
   function updateTPR().

   The parameter s can be used for applying a uniformly scaled transformation.

   An additional feature of the matrix is the interpolation between matrices.
   The function savePosition() stores the current possition. With each call to
   the function stepBack(), the current matrix is rotated to look more like
   the stored matrix. When the current and the stored matrix are the same,
   false is returned by stepBack().

*/
class Matrix3D {
private:
	bool lastanim;
	double t, p, r, s;
	double oldt, oldp, oldr;
	double xx, xy, xz;
	double yx, yy, yz;
	double zx, zy, zz;
	double angstep;
	static double pi, twopi;
	void updateMatrix();
	void updateTPR();
public:
	Matrix3D();
	void rotX(double);
	void rotY(double);
	void rotZ(double);
	void scale(double f);
	void transform(const double v[], double tv[], int nvert) const;
	void unit();
	void savePosition();
	bool stepBack();
	void setOrient(double t, double p, double r);
};

#endif
