/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Avril 2005                     */

public class Matrice {
  /* Tableau de 4x4 valeurs double pour le stockage       */
  /* des 4x4 reels d'un objet Matrice                     */
  double [][] t;

  /* Constructeur sans parametre avec initialisation      */
  /* d'une Matrice a la matrice identite                  */

  public Matrice() {
  /* Allocation de memoire pour le tableau t              */
  /* (initialisation a 0.0 realisee automatiquement)      */
    t = new double[4][4];
  /* Affectation a 1.0 des reels de la diagonale          */
    t[0][0] = t[1][1] = t[2][2] = t[3][3] = 1.0;
  }

  /* Methode de reaffectation complete d'une Matrice      */
  /* vers une transformation geometrique de type          */
  /* translation de tx en x, ty en y et tz en z           */
  /* tx, ty, tz : Reels decrivant les valeurs             */
  /*              de translation                          */

  public void toTranslation(double tx,double ty,double tz) {
  /* Affectation a 0.0 des trois premieres colonnes        */
  /* sauf sur la diagonale ou la valeur 1.0 est affectee   */
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 3 ; j++ )
        t[i][j] = ( i == j ) ? 1.0 : 0.0;
  /* Affectation de la troisieme colonne                   */
    t[0][3] = tx;
    t[1][3] = ty;
    t[2][3] = tz;
    t[3][3] = 1.0;
  }

  /* Methode de multiplication d'un vecteur par la matrice */
  /* Le resultat de la multiplication est stocke           */
  /* dans le vecteur                                       */
  /* v : Vecteur a multiplier et a utiliser                */
  /*     pour le stockage du resultat                      */

  public void multiplie(Vecteur v) {
  /* Utilisation d'un vecteur auxiliaire pour le produit   */
  /* matriciel (necessaire pour ne pas ecraser des valeurs */
  /* de v qui devraient etre reutilisees par la suite      */
    Vecteur nv = new Vecteur();
  /* Produit matriciel                                     */
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int k = 0 ; k < 4 ; k++ )
        nv.t[i] += t[i][k]*v.t[k];
  /* Reaffectation de v avec les valeurs de nv             */
    for ( int i = 0 ; i < 4 ; i++ )
      v.t[i] = nv.t[i];
  }

  /* Methode de multiplication d'une matrice               */
  /* par la matrice                                        */
  /* Le resultat de la multiplication est stocke           */
  /* dans la matrice                                       */
  /* m : Matrice a multiplier et a utiliser                */
  /*     pour le stockage du resultat                      */

  public void multiplie(Matrice m) {
  /* Utilisation d'une matrice auxiliaire pour le produit  */
  /* matriciel (necessaire pour ne pas ecraser des valeurs */
  /* de v qui devraient etre reutilisees par la suite      */
    Matrice nm = new Matrice();
  /* Produit matriciel                                     */
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ ) {
        nm.t[i][j] = 0.0;
        for ( int k = 0 ; k < 4 ; k++ )
          nm.t[i][j] += m.t[i][k]*t[k][j]; }
  /* Reaffectation de la Matrice avec les valeurs de nm    */
    for ( int i = 0 ; i < 4 ; i++ )
      for ( int j = 0 ; j < 4 ; j++ )
        t[i][j] = nm.t[i][j];
  }

  /* Surcharge de la methode toString                     */

  public String toString() {
    String s = new String();
    for ( int i = 0 ; i < 4 ; i++ )
      s = s+("["+t[i][0]+","+t[i][1]+","+t[i][2]+","+t[i][3]+"]");
    return(s);
  }
}