//
import java.awt.*;

//----- ROUTINES TO DO BASIC MATRIX MATH -----

public class Matrix
{
   public static void identity(double[][] matrix) {
      for (int i = 0 ; i < 4 ; i++)
      for (int j = 0 ; j < 4 ; j++)
         matrix[i][j] = (i == j ? 1 : 0);
   }

   public static double[][] tmp = new double[4][4];

   public static void copy(double[][] src, double[][] dst) {
      for (int i = 0 ; i < 4 ; i++)
      for (int j = 0 ; j < 4 ; j++)
         dst[i][j] = src[i][j];
   }

   public static void preMultiply(double[][] dst, double[][] b) {
      copy(dst, tmp);
      for (int i = 0 ; i < 4 ; i++)
      for (int j = 0 ; j < 4 ; j++) {
         dst[i][j] = 0;
         for (int k = 0 ; k < 4 ; k++)
            dst[i][j] += tmp[i][k] * b[k][j];
      }
   }

   public static void postMultiply(double[][] dst, double[][] b) {
      copy(dst, tmp);
      for (int i = 0 ; i < 4 ; i++)
      for (int j = 0 ; j < 4 ; j++) {
         dst[i][j] = 0;
         for (int k = 0 ; k < 4 ; k++)
            dst[i][j] += b[i][k] * tmp[k][j];
      }
   }

//----- ROUTINES TO ROTATE AND TRANSLATE MATRICES -----

   private static double[][] mat = new double[4][4];

   public static void translate(double[][] m, double x, double y, double z) {
      makeTranslationMatrix(mat, x,y,z);
      preMultiply(m, mat);
   }
   public static void rotateX(double[][] m, double theta) {
      makeRotationMatrix(mat, 1,2, theta);
      preMultiply(m, mat);
   }
   public static void rotateY(double[][] m, double theta) {
      makeRotationMatrix(mat, 2,0, theta);
      preMultiply(m, mat);
   }
   public static void rotateZ(double[][] m, double theta) {
      makeRotationMatrix(mat, 0,1, theta);
      preMultiply(m, mat);
   }
   public static void scale(double[][] m, double x, double y, double z) {
      makeScaleMatrix(mat, x,y,z);
      preMultiply(m, mat);
   }

//----- ROUTINES TO GENERATE TRANSFORMATION MATRICES -----

   private static void makeTranslationMatrix(double[][] m,
         double x, double y, double z) {
      identity(m);
      m[0][3] = x;
      m[1][3] = y;
      m[2][3] = z;
   }
   private static void makeRotationMatrix(double[][] m,
	 int i,int j,double theta) {
      identity(m);
      m[i][i] = m[j][j] = Math.cos(theta);
      m[i][j] = -Math.sin(theta);
      m[j][i] = -m[i][j];
   }
   private static void makeScaleMatrix(double[][] m,
	 double x,double y,double z) {
      identity(m);
      m[0][0] *= x;
      m[1][1] *= y;
      m[2][2] *= z;
   }
}